如何在swift中将字符索引从layoutManager转换为String scale
Posted
技术标签:
【中文标题】如何在swift中将字符索引从layoutManager转换为String scale【英文标题】:How to convert character index from layoutManager to String scale in swift 【发布时间】:2016-06-13 02:50:00 【问题描述】:如何在 swift 中将字符索引从 layoutManager 转换为 String scale? 这是我正在使用的代码:
let touchPoint: CGPoint = gesture.locationOfTouch(0, inView: self.definitionLabel)
let index = layoutManager.characterIndexForPoint(touchPoint, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
请不要告诉我在字符串字符集的第一个索引上使用 advanceBy()
函数,因为像 ò 这样的字符在 layoutManager 的比例中计为两个,但 swift 字符串将主题计为一次。
【问题讨论】:
【参考方案1】:从NSLayoutManager
返回的索引是“基于NSString
”,
即它是从字符串开头开始的 UTF-16 代码单元的数量
到给定点的字符。 (所以ò
实际上算作
一个,但 Emojis ?
算二,而标志 ??
甚至算四。)
要将该索引转换为有效的 Swift String
索引,您可以使用
与https://***.com/a/30404532/1187415中的方法相同:
let text = ... // the stored text
let i16 = text.utf16.startIndex.advancedBy(index, limit: text.utf16.endIndex)
// i16 is a String.UTF16View.Index
if let strIndex = String.Index(i16, within: text)
// strIndex is a String.CharacterView.Index
let char = text[strIndex]
print(char)
【讨论】:
【参考方案2】:为 Swift 5 更新
Martin R 的回答给了我大致的轮廓;这是工作中的 Swift 5 版本。我的适用于带有属性文本的 UITextView,但也适用于常规字符串以及 UITextField 和 UILabel。
func handleTap(_ sender: UIGestureRecognizer)
guard let textView = sender.view as? UITextView else return
guard let plaintext = textView.attributedText?.string else return
//guard let plaintext = textView.text else return
let location = sender.location(in: textView)
let charIndex = textView.layoutManager.characterIndex(for: location, in: textView.textContainer,
fractionOfDistanceBetweenInsertionPoints: nil)
if let strIndex = plaintext.utf16.index(plaintext.utf16.startIndex, offsetBy: charIndex, limitedBy: plaintext.utf16.endIndex)
let char = plaintext[strIndex]
print("Character tapped was \(char)")
let textTap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
textView.addGestureRecognizer(textTap)
【讨论】:
以上是关于如何在swift中将字符索引从layoutManager转换为String scale的主要内容,如果未能解决你的问题,请参考以下文章
如何从解析中的对象中获取 ObjectId 并在 swift 中将其呈现为字符串
如何在swift中将字符串“One”的字符转换为整数“1”[关闭]