使用attributedText在UITextView中实现撤消和重做

时间:2018-05-25 12:11:30

标签: swift uitextview nsattributedstring undo redo

我正在尝试将撤消重做功能添加到UITextView的实施中。我使用的是attributedText,而不仅仅是text的{​​{1}}属性。我已尝试使用UITextView中引用的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()
}

2 个答案:

答案 0 :(得分:1)

这不是OP问题的解决方案,而是替代方案

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

答案 1 :(得分:1)

这里有一些示例代码来处理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()            
    }
}

显然,您需要在故事板中连接操作/出口和文本视图的代理插座