Skip to content

Commit cdc3dc4

Browse files
author
Ignacio Romero Z.
committed
Merge pull request slackhq#33 from slackhq/undo-redo-support
Undo/Redo support
2 parents ef60515 + bd7ceec commit cdc3dc4

File tree

6 files changed

+81
-4
lines changed

6 files changed

+81
-4
lines changed

Examples/Messenger/Messenger/MessageViewController.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ - (void)fillWithText:(id)sender
112112
self.textView.text = [LoremIpsum sentencesWithNumber:sentences];
113113
}
114114
else {
115-
[self.textView slk_insertTextAtCaretRange:[LoremIpsum word]];
115+
[self.textView slk_insertTextAtCaretRange:[NSString stringWithFormat:@" %@", [LoremIpsum word]]];
116116
}
117117
}
118118

@@ -143,6 +143,10 @@ - (void)editRandomMessage:(id)sender
143143

144144
- (void)editLastMessage:(id)sender
145145
{
146+
if (self.textView.text > 0) {
147+
return;
148+
}
149+
146150
NSString *lastMessage = [self.messages firstObject];
147151
[self editText:lastMessage];
148152

Source/Additions/UITextView+SLKAdditions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,11 @@
6363
*/
6464
- (NSString *)slk_wordAtCaretRange:(NSRangePointer)range;
6565

66+
/**
67+
Registers the current text for future undo actions.
68+
69+
@param description A simple description associated with the Undo or Redo command.
70+
*/
71+
- (void)prepareForUndo:(NSString *)description;
72+
6673
@end

Source/Additions/UITextView+SLKAdditions.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ - (NSRange)slk_insertText:(NSString *)text inRange:(NSRange)range
9494
return NSMakeRange(0, 0);
9595
}
9696

97+
// Registers for undo management
98+
[self prepareForUndo:@"Text appending"];
99+
97100
// Append the new string at the caret position
98101
if (range.length == 0)
99102
{
@@ -164,4 +167,10 @@ - (NSString *)slk_wordAtRange:(NSRange)range rangeInText:(NSRangePointer)rangePo
164167
return word;
165168
}
166169

170+
- (void)prepareForUndo:(NSString *)description
171+
{
172+
[[self.undoManager prepareWithInvocationTarget:self] setText:self.text];
173+
[self.undoManager setActionName:description];
174+
}
175+
167176
@end

Source/Classes/SLKTextInputbar.m

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ @interface SLKTextInputbar () <UITextViewDelegate>
3636
@property (nonatomic, strong) NSLayoutConstraint *accessoryViewHC;
3737

3838
@property (nonatomic, strong) UILabel *charCountLabel;
39+
@property (nonatomic) BOOL newWordInserted;
3940

4041
@end
4142

@@ -126,6 +127,11 @@ - (SLKTextView *)textView
126127
[gesture addTarget:self action:@selector(willShowLoupe:)];
127128
}
128129
}
130+
131+
// Registers the Menu Controller for undo/redo actions
132+
UIMenuItem *undo = [[UIMenuItem alloc] initWithTitle:@"Undo" action:NSSelectorFromString(@"undo:")];
133+
UIMenuItem *redo = [[UIMenuItem alloc] initWithTitle:@"Redo" action:NSSelectorFromString(@"redo:")];
134+
[[UIMenuController sharedMenuController] setMenuItems:@[undo,redo]];
129135
}
130136
return _textView;
131137
}
@@ -364,13 +370,13 @@ - (void)updateCounter
364370
NSString *counter = nil;
365371

366372
if (self.counterStyle == SLKCounterStyleNone) {
367-
counter = [NSString stringWithFormat:@"%ld", text.length];
373+
counter = [NSString stringWithFormat:@"%ld", (unsigned long)text.length];
368374
}
369375
if (self.counterStyle == SLKCounterStyleSplit) {
370-
counter = [NSString stringWithFormat:@"%ld/%ld", text.length, self.maxCharCount];
376+
counter = [NSString stringWithFormat:@"%ld/%ld", (unsigned long)text.length, (unsigned long)self.maxCharCount];
371377
}
372378
if (self.counterStyle == SLKCounterStyleCountdown) {
373-
counter = [NSString stringWithFormat:@"%ld", text.length-self.maxCharCount];
379+
counter = [NSString stringWithFormat:@"%u", text.length-self.maxCharCount];
374380
}
375381

376382
self.charCountLabel.text = counter;
@@ -411,6 +417,13 @@ - (BOOL)textViewShouldEndEditing:(UITextView *)textView
411417

412418
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
413419
{
420+
self.newWordInserted = ([text rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].location != NSNotFound);
421+
422+
// Records text for undo for every new word
423+
if (self.newWordInserted) {
424+
[self.textView prepareForUndo:@"Word Change"];
425+
}
426+
414427
if ([text isEqualToString:@"\n"]) {
415428
//Detected break. Should insert new line break manually.
416429
[textView slk_insertNewLineBreak];

Source/Classes/SLKTextView.m

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,19 @@ - (void)setPlaceholderColor:(UIColor *)color
193193

194194
- (void)setText:(NSString *)text
195195
{
196+
// Registers for undo management
197+
[self prepareForUndo:@"Text Set"];
198+
196199
[super setText:text];
197200

198201
[[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self];
199202
}
200203

201204
- (void)setAttributedText:(NSAttributedString *)attributedText
202205
{
206+
// Registers for undo management
207+
[self prepareForUndo:@"Attributed Text Set"];
208+
203209
[super setAttributedText:attributedText];
204210
}
205211

@@ -213,6 +219,11 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
213219
return YES;
214220
}
215221

222+
if ((action == @selector(undo:) && [self.undoManager canUndo]) ||
223+
(action == @selector(redo:) && [self.undoManager canRedo])) {
224+
return YES;
225+
}
226+
216227
return [super canPerformAction:action withSender:sender];
217228
}
218229

@@ -231,6 +242,16 @@ - (void)paste:(id)sender
231242
}
232243
}
233244

245+
- (void)undo:(id)sender
246+
{
247+
[self.undoManager undo];
248+
}
249+
250+
- (void)redo:(id)sender
251+
{
252+
[self.undoManager redo];
253+
}
254+
234255
- (void)setFont:(UIFont *)font
235256
{
236257
[super setFont:font];

Source/Classes/SLKTextViewController.m

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,21 @@ - (void)didPressReturnKey:(id)sender
675675
[self performRightAction];
676676
}
677677

678+
- (void)didPressCommandZKeys:(id)sender
679+
{
680+
UIKeyCommand *keyComamnd = (UIKeyCommand *)sender;
681+
682+
if ((keyComamnd.modifierFlags & UIKeyModifierShift) > 0) {
683+
684+
if ([self.textView.undoManager canRedo]) {
685+
[self.textView.undoManager redo];
686+
}
687+
}
688+
else if ([self.textView.undoManager canUndo]) {
689+
[self.textView.undoManager undo];
690+
}
691+
}
692+
678693
- (void)didPressEscapeKey:(id)sender
679694
{
680695
if (self.isAutoCompleting) {
@@ -1240,6 +1255,14 @@ - (NSArray *)keyCommands
12401255
modifierFlags:UIKeyModifierControl
12411256
action:@selector(insertNewLineBreak)],
12421257

1258+
// Undo/Redo
1259+
[UIKeyCommand keyCommandWithInput:@"z"
1260+
modifierFlags:UIKeyModifierCommand
1261+
action:@selector(didPressCommandZKeys:)],
1262+
[UIKeyCommand keyCommandWithInput:@"z"
1263+
modifierFlags:UIKeyModifierShift|UIKeyModifierCommand
1264+
action:@selector(didPressCommandZKeys:)],
1265+
12431266
// Pressing Esc key
12441267
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape
12451268
modifierFlags:0

0 commit comments

Comments
 (0)