Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
Merge pull request #33 from slackhq/undo-redo-support
Browse files Browse the repository at this point in the history
Undo/Redo support
  • Loading branch information
Ignacio Romero Z. committed Oct 8, 2014
2 parents ef60515 + bd7ceec commit cdc3dc4
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 4 deletions.
6 changes: 5 additions & 1 deletion Examples/Messenger/Messenger/MessageViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ - (void)fillWithText:(id)sender
self.textView.text = [LoremIpsum sentencesWithNumber:sentences];
}
else {
[self.textView slk_insertTextAtCaretRange:[LoremIpsum word]];
[self.textView slk_insertTextAtCaretRange:[NSString stringWithFormat:@" %@", [LoremIpsum word]]];
}
}

Expand Down Expand Up @@ -143,6 +143,10 @@ - (void)editRandomMessage:(id)sender

- (void)editLastMessage:(id)sender
{
if (self.textView.text > 0) {
return;
}

NSString *lastMessage = [self.messages firstObject];
[self editText:lastMessage];

Expand Down
7 changes: 7 additions & 0 deletions Source/Additions/UITextView+SLKAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,11 @@
*/
- (NSString *)slk_wordAtCaretRange:(NSRangePointer)range;

/**
Registers the current text for future undo actions.
@param description A simple description associated with the Undo or Redo command.
*/
- (void)prepareForUndo:(NSString *)description;

@end
9 changes: 9 additions & 0 deletions Source/Additions/UITextView+SLKAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ - (NSRange)slk_insertText:(NSString *)text inRange:(NSRange)range
return NSMakeRange(0, 0);
}

// Registers for undo management
[self prepareForUndo:@"Text appending"];

// Append the new string at the caret position
if (range.length == 0)
{
Expand Down Expand Up @@ -164,4 +167,10 @@ - (NSString *)slk_wordAtRange:(NSRange)range rangeInText:(NSRangePointer)rangePo
return word;
}

- (void)prepareForUndo:(NSString *)description
{
[[self.undoManager prepareWithInvocationTarget:self] setText:self.text];
[self.undoManager setActionName:description];
}

@end
19 changes: 16 additions & 3 deletions Source/Classes/SLKTextInputbar.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ @interface SLKTextInputbar () <UITextViewDelegate>
@property (nonatomic, strong) NSLayoutConstraint *accessoryViewHC;

@property (nonatomic, strong) UILabel *charCountLabel;
@property (nonatomic) BOOL newWordInserted;

@end

Expand Down Expand Up @@ -126,6 +127,11 @@ - (SLKTextView *)textView
[gesture addTarget:self action:@selector(willShowLoupe:)];
}
}

// Registers the Menu Controller for undo/redo actions
UIMenuItem *undo = [[UIMenuItem alloc] initWithTitle:@"Undo" action:NSSelectorFromString(@"undo:")];
UIMenuItem *redo = [[UIMenuItem alloc] initWithTitle:@"Redo" action:NSSelectorFromString(@"redo:")];
[[UIMenuController sharedMenuController] setMenuItems:@[undo,redo]];
}
return _textView;
}
Expand Down Expand Up @@ -364,13 +370,13 @@ - (void)updateCounter
NSString *counter = nil;

if (self.counterStyle == SLKCounterStyleNone) {
counter = [NSString stringWithFormat:@"%ld", text.length];
counter = [NSString stringWithFormat:@"%ld", (unsigned long)text.length];
}
if (self.counterStyle == SLKCounterStyleSplit) {
counter = [NSString stringWithFormat:@"%ld/%ld", text.length, self.maxCharCount];
counter = [NSString stringWithFormat:@"%ld/%ld", (unsigned long)text.length, (unsigned long)self.maxCharCount];
}
if (self.counterStyle == SLKCounterStyleCountdown) {
counter = [NSString stringWithFormat:@"%ld", text.length-self.maxCharCount];
counter = [NSString stringWithFormat:@"%u", text.length-self.maxCharCount];
}

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

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
self.newWordInserted = ([text rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].location != NSNotFound);

// Records text for undo for every new word
if (self.newWordInserted) {
[self.textView prepareForUndo:@"Word Change"];
}

if ([text isEqualToString:@"\n"]) {
//Detected break. Should insert new line break manually.
[textView slk_insertNewLineBreak];
Expand Down
21 changes: 21 additions & 0 deletions Source/Classes/SLKTextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,19 @@ - (void)setPlaceholderColor:(UIColor *)color

- (void)setText:(NSString *)text
{
// Registers for undo management
[self prepareForUndo:@"Text Set"];

[super setText:text];

[[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self];
}

- (void)setAttributedText:(NSAttributedString *)attributedText
{
// Registers for undo management
[self prepareForUndo:@"Attributed Text Set"];

[super setAttributedText:attributedText];
}

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

if ((action == @selector(undo:) && [self.undoManager canUndo]) ||
(action == @selector(redo:) && [self.undoManager canRedo])) {
return YES;
}

return [super canPerformAction:action withSender:sender];
}

Expand All @@ -231,6 +242,16 @@ - (void)paste:(id)sender
}
}

- (void)undo:(id)sender
{
[self.undoManager undo];
}

- (void)redo:(id)sender
{
[self.undoManager redo];
}

- (void)setFont:(UIFont *)font
{
[super setFont:font];
Expand Down
23 changes: 23 additions & 0 deletions Source/Classes/SLKTextViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,21 @@ - (void)didPressReturnKey:(id)sender
[self performRightAction];
}

- (void)didPressCommandZKeys:(id)sender
{
UIKeyCommand *keyComamnd = (UIKeyCommand *)sender;

if ((keyComamnd.modifierFlags & UIKeyModifierShift) > 0) {

if ([self.textView.undoManager canRedo]) {
[self.textView.undoManager redo];
}
}
else if ([self.textView.undoManager canUndo]) {
[self.textView.undoManager undo];
}
}

- (void)didPressEscapeKey:(id)sender
{
if (self.isAutoCompleting) {
Expand Down Expand Up @@ -1240,6 +1255,14 @@ - (NSArray *)keyCommands
modifierFlags:UIKeyModifierControl
action:@selector(insertNewLineBreak)],

// Undo/Redo
[UIKeyCommand keyCommandWithInput:@"z"
modifierFlags:UIKeyModifierCommand
action:@selector(didPressCommandZKeys:)],
[UIKeyCommand keyCommandWithInput:@"z"
modifierFlags:UIKeyModifierShift|UIKeyModifierCommand
action:@selector(didPressCommandZKeys:)],

// Pressing Esc key
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape
modifierFlags:0
Expand Down

0 comments on commit cdc3dc4

Please sign in to comment.