路易斯·德尔加多的出色答卷给了我很大的起跳点,但有几个缺点:
- 总是清除该字符串的结尾
- 不处理插入令牌
- 不处理修改包括令牌的选定文本
这里是我的版本(SWIFT 4):
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if range.location < textView.attributedText.length {
var shouldReplace = false
var tokenAttrRange = NSRange()
var currentReplacementRange = range
let tokenAttr = NSAttributedStringKey.foregroundColor
if range.length == 0 {
if nil != textView.attributedText.attribute(tokenAttr, at: range.location, effectiveRange: &tokenAttrRange) {
currentReplacementRange = NSUnionRange(currentReplacementRange, tokenAttrRange)
shouldReplace = true
}
} else {
// search the range for any instances of the desired text attribute
textView.attributedText.enumerateAttribute(tokenAttr, in: range, options: .longestEffectiveRangeNotRequired, using: { (value, attrRange, stop) in
// get the attribute's full range and merge it with the original
if nil != textView.attributedText.attribute(tokenAttr, at: attrRange.location, effectiveRange: &tokenAttrRange) {
currentReplacementRange = NSUnionRange(currentReplacementRange, tokenAttrRange)
shouldReplace = true
}
})
}
if shouldReplace {
// remove the token attr, and then replace the characters with the input str (which can be empty on a backspace)
let mutableAttributedText = textView.attributedText.mutableCopy() as! NSMutableAttributedString
mutableAttributedText.removeAttribute(tokenAttr, range: currentReplacementRange)
mutableAttributedText.replaceCharacters(in: currentReplacementRange, with: text)
textView.attributedText = mutableAttributedText
// set the cursor position to the end of the edited location
if let cursorPosition = textView.position(from: textView.beginningOfDocument, offset: currentReplacementRange.location + text.lengthOfBytes(using: .utf8)) {
textView.selectedTextRange = textView.textRange(from: cursorPosition, to: cursorPosition)
}
return false
}
}
return true
}
如果你需要重写一个超类,加上override关键字和,而不是在最后返回true,则返回
super.textView(textView, shouldChangeTextIn: range, replacementText: text)
你可以将tokenAttr
更改为任何标准或自定义文本属性。如果将enumerateAttribute更改为enumerateAttributes,则甚至可以查找文本属性的组合。
如何子类化NSAttributedString'并添加额外的属性来捕获字符串包含用户名的事实? –