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

UIViewController如何拦截UITextView的复制/粘贴等编辑操作?

问题根因

你写的代码无法触发的核心逻辑是UIResponder的事件传递规则:当用户点击编辑菜单的复制/粘贴选项时,系统会将对应事件优先发送给当前的第一响应者。当UITextView处于激活编辑状态时,它本身就是第一响应者,copy:、paste:这类编辑事件会直接被UITextView实例接收处理,根本不会沿着响应链传递到上层的UIViewController,因此你在VC中重写的对应方法永远不会被调用。
另外你重写VC的canBecomeFirstResponder返回true没有实际作用——编辑操作触发时第一响应者始终是聚焦状态的UITextView,VC不会抢占第一响应者身份。

实现方案

方案1:子类化UITextView重写编辑方法(推荐,最稳定)

这是官方推荐的实现方式,不需要改动VC层的响应逻辑:

  • 新建UITextView的自定义子类,重写你需要拦截的编辑方法,按需决定是否调用super保留系统默认行为
  • 把项目中原来使用的UITextView替换为这个自定义子类即可,需要和VC交互的话可以通过代理、闭包把事件回调出去
    示例代码:
class ActionInterceptTextView: UITextView {
    override func copy(_ sender: Any?) {
        // 写入自定义拦截逻辑
        NSLog("Copy action triggered")
        // 需要保留系统默认复制能力就调用super,不需要就注释掉这行
        super.copy(sender)
    }

    override func paste(_ sender: Any?) {
        NSLog("Paste action triggered")
        super.paste(sender)
    }

    // 可选:自定义控制编辑菜单的选项显隐
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        switch action {
        case #selector(copy(_:)), #selector(paste(_:)), #selector(cut(_:)):
            return true // 业务需要隐藏对应选项时返回false即可
        default:
            return super.canPerformAction(action, withSender: sender)
        }
    }
}

方案2:通过UITextViewDelegate拦截文本类操作(无需子类化)

如果只是需要拦截粘贴带来的文本修改,不需要处理复制、剪切操作,可以直接用UITextView自带的代理方法,不需要新建子类:

  • 实现textView(_:shouldChangeTextIn:replacementText:)代理方法,结合UIPasteboard的内容判断是否为粘贴触发的修改,执行自定义逻辑后返回false即可拦截默认粘贴行为,返回true则放行。
  • 注意这个方案无法拦截复制、剪切这类不修改文本内容的操作,适用场景有限。

避坑提醒

不要尝试通过让textView放弃第一响应者、让VC成为第一响应者的方式实现拦截——这种方式会直接让textView失去焦点,编辑菜单会瞬间消失,根本无法触发后续的复制粘贴操作,会破坏正常的交互逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:18:49