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

如何阻止图片拖入支持富文本编辑的UITextView

如何限制UITextView仅允许文本内容(保留富文本编辑功能)

嘿,我懂你的需求——你做了个支持富文本编辑的UITextView,能改粗体、斜体、下划线、字体字号这些格式,但现在能拖进图片,想把这个口子堵上,同时保留原本的文本格式编辑功能对吧?这有几个实用的办法,给你捋捋:

方法一:直接禁用拖放交互

图片拖入本质是系统的拖放(Drop)交互在起作用,我们可以直接把UITextView的拖放接收能力关掉,从源头阻止图片拖入:

override init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    allowsEditingTextAttributes = true
    
    // 移除默认的拖放交互
    for interaction in interactions {
        if interaction is UIDropInteraction {
            removeInteraction(interaction)
        }
    }
}

或者更简洁的写法,直接禁用拖放交互:

override init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    allowsEditingTextAttributes = true
    dropInteraction?.isEnabled = false
}

方法二:拦截非文本的粘贴操作

除了拖放,用户还可能通过粘贴把图片塞进来,所以我们可以重写粘贴相关的方法,只允许粘贴纯文本:

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    // 只允许粘贴文本内容
    if action == #selector(paste(_:)) {
        guard UIPasteboard.general.hasStrings else {
            return false
        }
        return true
    }
    // 保留其他富文本编辑操作(比如粗体、斜体、下划线这些)
    return super.canPerformAction(action, withSender: sender)
}

override func paste(_ sender: Any?) {
    guard let text = UIPasteboard.general.string else {
        return
    }
    // 执行文本粘贴,同时保留光标位置逻辑
    let selectedRange = self.selectedRange
    self.replace(selectedRange, withText: text)
    self.selectedRange = NSRange(location: selectedRange.location + text.count, length: 0)
}

方法三:过滤已插入的图片(兜底方案)

如果担心还有漏网之鱼(比如某些特殊场景下图片被插入),可以监听文本变化,自动移除所有图片附件:

override init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    allowsEditingTextAttributes = true
    delegate = self
}

// 扩展实现UITextViewDelegate
extension YourTextView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        let mutableAttributedText = textView.attributedText.mutableCopy() as! NSMutableAttributedString
        var currentRange = NSRange(location: 0, length: mutableAttributedText.length)
        
        while currentRange.location < mutableAttributedText.length {
            // 检查当前位置是否有图片附件
            if let attachment = mutableAttributedText.attribute(.attachment, at: currentRange.location, effectiveRange: &currentRange) as? NSTextAttachment {
                // 移除图片附件对应的内容
                mutableAttributedText.deleteCharacters(in: currentRange)
            } else {
                // 移动到下一段内容
                currentRange.location += currentRange.length
                currentRange.length = mutableAttributedText.length - currentRange.location
            }
        }
        
        textView.attributedText = mutableAttributedText
    }
}

推荐方案

我建议你把方法一+方法二结合起来用,既从源头禁用拖放,又拦截非文本粘贴,这样就能彻底阻止图片进入UITextView,同时完全保留你需要的富文本格式编辑功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:02:42