UITextView滚动后无法准确获取点击单词的问题求助
解决UITextView滚动后点击获取单词不准确的问题
你遇到的核心问题是手动调整点击坐标的方式不符合UITextView文本布局的逻辑——你直接把contentOffsetY加到点击坐标上,但这种方式没有考虑文本容器的内边距、文本排版的行高差异等细节,滚动后自然无法精准匹配到点击的单词。
下面是修正后的完整解决方案:
步骤1:移除错误的坐标调整逻辑,改用LayoutManager计算准确位置
UITextView的layoutManager已经封装了文本坐标的计算逻辑,我们可以直接用它来获取点击位置对应的文本索引,无需手动调整偏移量。
步骤2:修正点击手势处理代码
替换你原来的handleTap和word(atPosition:)方法为以下代码:
@objc func handleTap(_ sender: UITapGestureRecognizer) { notesTextView.isEditable = true notesTextView.textColor = UIColor.white guard let textView = sender.view as? UITextView else { return } let tapPoint = sender.location(in: textView) // 通过LayoutManager获取点击位置对应的Glyph索引 let glyphIndex = textView.layoutManager.glyphIndex(for: tapPoint, in: textView.textContainer, fractionOfDistanceThroughGlyph: nil) // 将Glyph索引转换为UITextPosition guard let tapPosition = textView.position(from: textView.beginningOfDocument, offset: glyphIndex) else { return } // 获取点击位置所在的单词范围 if let wordRange = textView.tokenizer.rangeEnclosingPosition(tapPosition, with: .word, inDirection: UITextDirection(rawValue: 1)) { if let tappedWord = textView.text(in: wordRange) { print("Word: \(tappedWord)") // 这里可以添加你对选中单词的后续处理逻辑 } } }
关键说明
layoutManager.glyphIndex(for:in:fractionOfDistanceThroughGlyph:):会自动处理滚动偏移、文本容器内边距、文本排版等因素,返回点击位置对应的字形(Glyph)索引,这是匹配文本位置的准确方式。- 确保你的UITextView初始状态下
isSelectable属性为true(即使isEditable为false)——因为tokenizer需要文本可选才能正常解析单词范围,你可以在初始化时设置:notesTextView.isSelectable = true notesTextView.isEditable = false
这样修改后,无论UITextView是否滚动,都能精准获取到点击的单词啦!
内容的提问来源于stack exchange,提问作者Amrit Sidhu
相关产品推荐
相关产品推荐

