UITextView的caretRect换行后minX与maxX返回无穷大问题求助
解决UITextView换行后caretRect返回无穷大导致崩溃的问题
问题原因
UITextView输入换行后,文本布局可能尚未完成,此时调用caretRect(for:)会返回CGRect.infinite,直接访问其minX就会触发崩溃。
解决方案
防御性判断,跳过无效Rect
在赋值前先检查Rect是否有效,避免异常值引发崩溃:if let cursorPosition = messageTextView.selectedTextRange?.start { let caretPositionRect = messageTextView.caretRect(for: cursorPosition) guard !caretPositionRect.isInfinite else { return } leadingAnchor.constant = caretPositionRect.minX }通过LayoutManager获取准确光标位置
直接利用UITextView负责文本布局的layoutManager类获取光标对应的glyph位置,结果更可靠:if let cursorPosition = messageTextView.selectedTextRange?.start { let glyphIndex = messageTextView.layoutManager.glyphIndex(for: cursorPosition, in: messageTextView.textContainer) var glyphRect = messageTextView.layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 0), in: messageTextView.textContainer) glyphRect = messageTextView.convert(glyphRect, from: messageTextView.layoutManager.textContainer) leadingAnchor.constant = glyphRect.minX }等待布局完成后再执行代码
在textViewDidChange中通过DispatchQueue.main.async延迟执行,让UITextView完成文本布局后再获取光标位置:func textViewDidChange(_ textView: UITextView) { DispatchQueue.main.async { if let cursorPosition = textView.selectedTextRange?.start { let caretPositionRect = textView.caretRect(for: cursorPosition) leadingAnchor.constant = caretPositionRect.minX } } }
内容的提问来源于stack exchange,提问作者newest_tfriz
相关产品推荐
相关产品推荐

