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

UITextView子类自定义NSAttributedString属性与自动补全问题

解决UITextView自动补全丢失自定义属性的问题

一、重写核心替换方法

系统处理键盘自动补全替换时,实际会调用replaceCharacters(in:with:)——这是UITextView继承自UITextInput协议的核心方法,你之前可能漏掉了它的重写。

直接重写这个方法,在替换时保留自定义属性:

override func replaceCharacters(in range: NSRange, with text: String) {
    // 获取替换位置的原有属性(包含你的.custom自定义属性)
    guard let targetAttributes = attributedText?.attributes(at: range.location, effectiveRange: nil) else {
        super.replaceCharacters(in: range, with: text)
        return
    }
    
    // 用原有属性创建带自定义标记的新文本
    let newAttributedText = NSAttributedString(string: text, attributes: targetAttributes)
    
    // 调用父类方法完成替换,确保属性不丢失
    super.replaceCharacters(in: range, with: newAttributedText)
}

二、兜底修复方案

如果遇到某些系统版本的补全逻辑差异,还可以通过监听文本变化通知,事后修复丢失的自定义属性:

// 子类初始化时添加监听
override init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    setupAttributeFixObserver()
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    setupAttributeFixObserver()
}

private func setupAttributeFixObserver() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(recoverCustomAttributes),
        name: UITextView.textDidChangeNotification,
        object: self
    )
}

@objc private func recoverCustomAttributes() {
    guard let fullText = attributedText else { return }
    let mutableText = NSMutableAttributedString(attributedString: fullText)
    
    // 这里假设自定义属性是全局统一的,取第一个字符的属性作为基准补全
    guard let baseAttrs = fullText.attributes(at: 0, effectiveRange: nil) else { return }
    mutableText.addAttributes(baseAttrs, range: NSRange(location: 0, length: fullText.length))
    
    attributedText = mutableText
}

三、关键说明

  • 之前insertText只收到换行符,是因为系统自动补全的逻辑是先替换选中文本,再处理后续的换行插入,真正的替换逻辑在replaceCharacters(in:with:)里。
  • 这个重写方法会覆盖所有文本替换场景(包括输入、粘贴、自动补全),不需要单独区分补全场景,统一处理即可保证属性不丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:04:56