Implementing undo and redo in a UITextView with attributedText
Here's some sample code to handle undo/redo for a UITextView
. Don't forget to update your undo/redo buttons state initially and after each change to the text.
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var undoButton: UIButton!
@IBOutlet weak var redoButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
updateUndoButtons()
}
@IBAction func undo(_ sender: Any) {
textView.undoManager?.undo()
updateUndoButtons()
}
@IBAction func redo(_ sender: Any) {
textView.undoManager?.redo()
updateUndoButtons()
}
func updateUndoButtons() {
undoButton.isEnabled = textView.undoManager?.canUndo ?? false
redoButton.isEnabled = textView.undoManager?.canRedo ?? false
}
}
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
updateUndoButtons()
}
}
Obviously you'll need to hook up the actions/outlets and the text view's delegate outlet in a storyboard
How to implement undo with NSTextview
From Cocoa Text Architecture Guide: Text Editing – Text Change Notifications and Delegate Messages:
In actually making changes to the text, you must ensure that the changes are properly performed and recorded by different parts of the text system. You do this by bracketing each batch of potential changes with shouldChangeTextInRange:replacementString: and didChangeText messages. These methods ensure that the appropriate delegate messages are sent and notifications posted. …
In my experience, that includes generating the relevant undo operation.
So, you would do:
if ([self.textView shouldChangeTextInRange:selectedRange replacementString:stringToReplace])
{
[[self.textView textStorage] beginEditing];
[[self.textView textStorage] replaceCharactersInRange:selectedRange withString:stringToReplace];
[[self.textView textStorage] endEditing];
[self.textView didChangeText];
}
iOS out of range crash when using shake to undo a paste into UITextView with overwritten shouldChangeCharactersInRange
If text for UITextView
or UITextField
is changed programatically while it is being changed the undo manager would not be updated and will keep track of wrong actions.
To avoid crash we should reset undo manager so it does not contain dirty actions.
[textField.undoManager removeAllActions];
Bold & Non-Bold Text In uitextView - iOS
You can use NSAttributedString to custom the string format:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
var textV = new UITextView(new CGRect(100, 100, 300, 300));
var myMutableString = new NSMutableAttributedString("How ? \n Some text \n Who ? \n Some text");
var range1 = myMutableString.MutableString.LocalizedStandardRangeOfString(new NSString("How ?"));
var range2 = myMutableString.MutableString.LocalizedStandardRangeOfString(new NSString("Who ?"));
var range3 = myMutableString.MutableString.LocalizedStandardRangeOfString(new NSString("Some text"));
myMutableString.AddAttribute(UIStringAttributeKey.Font, UIFont.SystemFontOfSize(24), range1);
myMutableString.AddAttribute(UIStringAttributeKey.Font, UIFont.SystemFontOfSize(24), range2);
myMutableString.AddAttribute(UIStringAttributeKey.Font, UIFont.SystemFontOfSize(14), range3);
textV.AttributedText = myMutableString;
View.AddSubview(textV);
}
Here is the result:
Related Topics
Firebase Swift 3 Get List of Child in a Array
Calling C++ from Swift - What Is The Equivalent of Std::Vector<T>
Swift 4, Coreplot, Send Chart via Mail App (With Messageui)
Xcode 9.3 Watchkit Crash on Wkinterfacebutton Tap
Error Validating Cms Signature
Literal Numbers in Floatingpoint Protocol
List Inside Scrollview Is Not Displayed on Watchos
How to Stop Firestore Pagination When Searched Data Are Loaded in Tableview
Swiftui Custom View Repeat Forever Animation Show as Unexpected
Swift: Convert Byte Array into Ciimage
Spritekit and Swiftui, Change Scene a Better Way
How to List All Available Patterns in a Scdynamicstorage
Bar Button Item Tint Color Not Working
Remove Add Calendar Button from Calendar Chooser
Swiftui: Why Doesn't Observedobject Work in Appdelegate
How to Insert a Row in Tableview Without Using Reloaddata Function in Cocoa