You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让UITextView使用视图控制器的undoManager以统一撤销栈?

统一PKCanvasView与UITextView的单一撤销栈实现

要让UITextView复用视图控制器的undoManager,核心是替换UITextView默认的只读undoManager属性——因为UITextView自身的undoManager是只读的,无法直接赋值,所以需要通过自定义子类重写该属性来实现。

步骤1:自定义UITextView子类

创建一个继承自UITextView的子类,添加属性持有外部传入的共享undoManager,并重写undoManager方法返回这个共享实例:

Swift版本:

class SharedUndoTextView: UITextView {
    // 弱引用避免循环引用
    weak var sharedUndoManager: UndoManager?
    
    override var undoManager: UndoManager? {
        // 优先使用共享的undoManager, fallback到默认实现
        return sharedUndoManager ?? super.undoManager
    }
}

Objective-C版本:

// SharedUndoTextView.h
#import <UIKit/UIKit.h>

@interface SharedUndoTextView : UITextView
@property (nonatomic, weak) NSUndoManager *sharedUndoManager;
@end

// SharedUndoTextView.m
#import "SharedUndoTextView.h"

@implementation SharedUndoTextView

- (NSUndoManager *)undoManager {
    return self.sharedUndoManager ?: [super undoManager];
}

@end

步骤2:在视图控制器中关联共享UndoManager

在你的视图控制器中,确保自身持有一个全局的undoManager,并将所有自定义UITextView的sharedUndoManager指向它:

Swift版本:

class CanvasTextViewController: UIViewController {
    // 懒加载全局undoManager,可自定义撤销层级
    lazy var undoManager: UndoManager = {
        let manager = UndoManager()
        manager.levelsOfUndo = 20 // 设置最大撤销次数
        manager.groupsByEvent = true // 合并连续操作(如快速打字)
        return manager
    }()
    
    // IBOutlet关联的自定义TextView
    @IBOutlet weak var textView1: SharedUndoTextView!
    @IBOutlet weak var textView2: SharedUndoTextView!
    // 你的PKCanvasView
    @IBOutlet weak var canvasView: PKCanvasView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 给所有TextView绑定共享undoManager
        textView1.sharedUndoManager = self.undoManager
        textView2.sharedUndoManager = self.undoManager
        
        // 确保PKCanvasView也使用同一个undoManager(默认已继承父视图,但显式设置更稳妥)
        canvasView.undoManager = self.undoManager
    }
}

关键注意事项

  • 如果使用Storyboard/XIB创建UITextView,需在界面编辑器中将控件的类改为SharedUndoTextView,再关联IBOutlet。
  • UITextView的文本变更会自动注册到共享undoManager中,无需额外手动注册;如果有自定义文本操作,需调用undoManager.registerUndo(withTarget:handler:)手动添加撤销逻辑。
  • 测试时验证撤销/重做流程:PKToolPicker的按钮应能依次撤销PKCanvasView的绘图操作和UITextView的文本修改,反之亦然,实现统一的撤销栈。

内容的提问来源于stack exchange,提问作者Hamster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:17:34