Swift 在带有AttributeText的UITextView中实现撤消和重做
我正在尝试向我的Swift 在带有AttributeText的UITextView中实现撤消和重做,swift,uitextview,nsattributedstring,undo,redo,Swift,Uitextview,Nsattributedstring,Undo,Redo,我正在尝试向我的UITextView实现中添加undo和redo功能。我使用的是attributedText,而不仅仅是UITextView的text属性。我已经尝试使用中引用的undoManager中的函数调用,但是似乎什么都没有发生。我很惊讶,我在谷歌上找不到关于这个主题的任何东西。在使用attributedText/对UITextView执行撤消和重做之前,是否有人遇到过此问题?是否知道如何执行此操作 示例代码 textView.attributedText = NSMutableAttr
UITextView
实现中添加undo和redo功能。我使用的是attributedText
,而不仅仅是UITextView
的text
属性。我已经尝试使用中引用的undoManager
中的函数调用,但是似乎什么都没有发生。我很惊讶,我在谷歌上找不到关于这个主题的任何东西。在使用attributedText
/对UITextView
执行撤消和重做之前,是否有人遇到过此问题?是否知道如何执行此操作
示例代码
textView.attributedText = NSMutableAttributedString(string: "SOME TEXT")
@objc func undo(_ sender: UIButton) {
textView.undoManager?.undo()
}
@objc func redo(_ sender: UIButton) {
textView.undoManager?.redo()
}
这不是OP问题的解决方案,而是一个粗糙的替代方案
textView.attributedText = NSMutableAttributedString(string: "SOME TEXT")
@objc func undo(_ sender: UIButton) {
textView.undoManager?.undo()
}
@objc func redo(_ sender: UIButton) {
textView.undoManager?.redo()
}
我以前没有处理过这个问题,我认为可以通过实现堆栈数据结构并结合UITextField委托回调
textViewDidFinishEditing(textField:UITextField)
来实现。其思想是,对于用户对文本字段所做的每一次更改,您都将当前属性化字符串放在堆栈上。撤消功能通过将一个按钮连接到堆栈,弹出最近的属性字符串,并相应地设置textfields属性字符串属性来发挥作用 下面是一些用于处理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()
}
}
显然,您需要在故事板中连接操作/出口和文本视图的代理出口是否可以包含代码以显示注册撤消操作的位置?请确保
iAction
已连接到您的ui按钮
。我已经测试了您的代码是否对我有效。@sanch yes这就是问题所在,但不确定如何注册所有属性等@abecardiopoint我接受了您的编辑,但实际上函数是通过编程方式调用的,因此不需要@IBAction
,我认为这将回答您的大多数问题@您的编辑不正确。编程UI不需要iAction,它字面上代表InterfaceBuilderAction。Op设置objc句柄是正确的,因为选择器是一个objc方法,swift 4中不再暗示类型推断,因此无需自己编写,这是免费的。每个UIResponder
都有一个可选的undoManager
,用于处理堆栈上的推送/弹出操作。@AshleyMills,你肯定是对的。我在回答中添加了一个限定语句。谢谢!这绝对是最好的解决方案。我已经用我想要的特性/怪癖从零开始实现了我自己的版本,但我希望这对任何想在UITextView上实现undo/redo的人都有用