使用属性文本在 UITextView 中实现撤消和重做



我正在尝试将撤消重做功能添加到我的UITextView实现中。我正在使用attributedText,而不仅仅是UITextViewtext属性。我已经尝试使用Apple文档中引用的undoManager函数调用,但是似乎没有任何反应。我很惊讶我无法通过谷歌搜索找到任何关于这个主题的内容。有没有人遇到过这个问题/在UITextView上实现了撤消和重做attributedText/知道如何解决这个问题?

示例代码

textView.attributedText = NSMutableAttributedString(string: "SOME TEXT")
@objc func undo(_ sender: UIButton) {
textView.undoManager?.undo()
}
@objc func redo(_ sender: UIButton) {
textView.undoManager?.redo()
}

这里有一些示例代码来处理UITextView的撤消/重做。不要忘记在最初和每次更改文本后更新撤消/重做按钮状态。

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()            
}
}

显然,您需要在情节提要中挂接操作/出口和文本视图的委托出口

这不是OP问题的解决方案,而是一个粗略的替代方案

在我认为您可以通过实现堆栈数据结构与 UITextField 委托回调textViewDidFinishEditing(textField: UITextField)来实现这一点之前,我还没有处理过这个问题。这个想法是,对于用户对文本字段所做的每次更改,您都将当前属性字符串放置到堆栈上。撤消功能通过将按钮连接到堆栈并弹出最新的属性字符串并相应地设置文本字段属性字符串属性来发挥作用。

最新更新