0

I am implementing a format bar which is used for Rich Text Editing. Among them I have two buttons Undo and Redo. I have documentation for both on apple developers but could not come up to make Redo work. Problem is I have a UITextView. Whenever user writes each word is registered as undo operation in [textView undoManager] like this in shouldChangeTextInRange.

When user clicks on Undo Button, it is done successfully via code [[_myTextView undoManager] undo]. But when user clicks on Redo Button, redo is not performed.

I have even printed the name when user clicks on redo like this [[_myTextView undoManager] redoActionName] and it prints "Change", name of Action. but nothing happens on the text of TextView.

I have searched alot but in every case people are using Interface Builder for undo and automatic redo but I am working with code. Also note even on Ipad the build in button on keyboard for redo does not work after i do undo with keyboard button. Kindly guide me.

-(BOOL) textView: (UITextView *)textView shouldChangeTextInRange:(NSRange) range replacementText: (NSString *) text{

    [[textView undoManager] registerUndoWithTarget:self selector:@selector(revertTextView:) object:textView.attributedText];
    [[textView undoManager] setActionName:NSLocalizedString(@"Change",@" undo")];

}

-(void) revertTextView: (NSAttributedString *) textViewAttString{

    _myTextView.attributedText = textViewAttributedString;

}

-(IBAction) undoClick{

    [[_myTextView undoManager] undo];

}

-(IBAction) redoClick{

    [[_myTextView undoManager] redo];

}
l0gg3r
  • 8,864
  • 3
  • 26
  • 46
Sahar
  • 53
  • 7

1 Answers1

0

Do not call any registers
TextView already has NSUndoManager and it's configured

What you need to do is

- (IBAction)undoPressed
{
    [[self.myTextView undoManager] undo];
}

- (IBAction)redoPressed
{
    [[self.myTextView undoManager] redo];
}
l0gg3r
  • 8,864
  • 3
  • 26
  • 46
  • I tried and it does not work. [[self.myTextView undoManager] undo] is equivalent to [[_myTextView undoManager] undo] because I have linked it via Interface Builder. Also **Undo is working properly, Redo does not work**. Like if I write **abcd** and press undo it becomes abc but when press redo it remains as **abc**. I had also tried with **[[self undoManager] undo]** in that case too only undo works. – Sahar Sep 26 '14 at 07:51
  • Just delete, textView:shouldChangeTextInRange: and revertTextView: , and it will start working – l0gg3r Sep 26 '14 at 07:54
  • I deleted both and then neither undo nor redo worked. – Sahar Sep 26 '14 at 09:30
  • this means another code is changing behavior of undoManager. by default it should work properly. – l0gg3r Sep 26 '14 at 09:32
  • You are right. I have checked everything in detail. Whats happening is i change the attributedText in shouldChangeTextInRange and sets the text of TextView as new attributedText and return FALSE. If I don't return False system also writes on TextView and there are dual characters written in TextView like this aabbcc. One character by system itself and one by me. Also if I return TRUE, undo redo both works fine and system saves all information automatically after each word is typed. But undo removes all characters that are noted by system like aabbcc becomes aabbc then aabc. – Sahar Sep 26 '14 at 10:55
  • So, I have to return TRUE from **shouldChangeTextInRange** for proper working but then I have dual characters. I cannot do compromise. I want both things at the same time and cannot figure out any solution for replacing characters in such a way that I don't have dual characters if I opt for returning TRUE from **shouldChangeTextInRange**. – Sahar Sep 26 '14 at 10:57
  • Really thanks, your answer let me think in another direction. I appreciate. But trouble still exists with me. – Sahar Sep 26 '14 at 10:58
  • hm..., let me know about news – l0gg3r Sep 26 '14 at 11:03
  • Thanks for your response. I'll sure do. – Sahar Sep 29 '14 at 05:58