ios - UITextField:attributeText 在 resignFirstResponder 时无法正常工作
问题描述
我有一个UITextField
和一个按钮,该按钮突出显示文本字段文本的最后一个字母以及关闭键盘:
private func highlightLast() {
guard let text = textField.text, text.count > 1 else {
return
}
textField.resignFirstResponder()
let attributedString = NSMutableAttributedString(string: text)
attributedString.addAttribute(.backgroundColor, value: UIColor.yellow, range: NSRange(location: text.count - 1, length: 1))
textField.attributedText = attributedString
}
第一次点击按钮可以正常工作,但如果我再次点击文本字段以显示键盘,然后再次点击按钮,整个文本都会突出显示:
稍作改动,无论我做了多少次,以下操作都可以正常工作:
- 在不关闭键盘的情况下突出显示最后一个字母或任何字母。
- 突出显示不是最后一个字母的任何字母,并关闭键盘。
这让我想知道我是否对范围做错了,或者其他一些基于键盘关闭的实现差异?
任何帮助表示赞赏!
更新:
我检查了视图层次结构,下面是它工作的时间(即仅突出显示最后一个字母)与它不工作的时间(即完全突出显示的文本):
当它按预期工作时:
Tes{
NSBackgroundColor = "<UIDynamicSystemColor: 0x600001c89b40; name = systemBackgroundColor>";
NSColor = "<UIDynamicSystemColor: 0x600001c8a780; name = labelColor>";
NSFont = "<UICTFont: 0x7fad17d0c120> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 4, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 65535";
NSShadow = "NSShadow {0, -1} color = {(null)}";
}t{
NSBackgroundColor = "UIExtendedSRGBColorSpace 1 1 0 1";
NSColor = "<UIDynamicSystemColor: 0x600001c8a780; name = labelColor>";
NSFont = "<UICTFont: 0x7fad17d0c120> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 4, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 65535";
NSShadow = "NSShadow {0, -1} color = {(null)}";
}
当整个文本突出显示不起作用时:
Test{
NSBackgroundColor = "UIExtendedSRGBColorSpace 1 1 0 1";
NSColor = "<UIDynamicSystemColor: 0x600001c8a780; name = labelColor>";
NSFont = "<UICTFont: 0x7fad17d0c120> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 4, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 65535";
NSShadow = "NSShadow {0, -1} color = {(null)}";
}
解决方案
来自 Apple 的文档:
讨论
此属性默认为 nil。为该属性分配一个新值也会用相同的字符串数据替换 text 属性的值,尽管没有任何格式信息。此外,分配新值会更新字体、textColor 和其他与样式相关的属性中的值,以便它们反映从属性字符串中位置 0 开始的样式信息。
因此,您需要“重置”文本字段的属性。
一种方法:
override func viewDidLoad() {
super.viewDidLoad()
textField.addTarget(self, action: #selector(editingDidBegin(_:)), for: .editingDidBegin)
}
@objc func editingDidBegin(_ sender: Any) {
let s = textField.text ?? ""
textField.attributedText = NSAttributedString(string: s)
}
推荐阅读
- pine-script - Pine-Script:从已知范围中选择一个栏 [仅]
- c++ - 函数 C++ 的多重声明
- excel - 从另一张纸上的单元格中获取价值
- directus - Directus - 在挂钩中创建文件
- javascript - 保存新创建的角色和频道的 ID
- javascript - Firebase 实时数据库规则在前端不起作用
- javascript - 如何在 Firebase Cloud Function 条件下使用模板文字
- typescript - TypeScript 动态联合
- r - 连接列名和R中的第一行
- python - 使用 Tkinter 在框架内放置框架时遇到困难