如何为UITextView中的NSTextAttachment配置圆形UIPointerInteraction?
实现自定义UITextView中NSTextAttachment的圆形悬停指针
要让自定义UITextView里的NSTextAttachment在触控板悬停时显示圆形指针,核心是通过UIPointerInteraction配置指针样式,以下是两种可行方案:
方案一:给UITextView全局添加指针交互(适配所有附件)
通过监听UITextView的悬停位置,判断是否落在附件范围内,动态切换指针样式:
import UIKit class CustomTextView: UITextView, UIPointerInteractionDelegate { override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) setupPointerInteraction() } required init?(coder: NSCoder) { super.init(coder: coder) setupPointerInteraction() } private func setupPointerInteraction() { let pointerInteraction = UIPointerInteraction(delegate: self) addInteraction(pointerInteraction) } // 判断悬停点是否对应某个文本附件 private func getAttachmentAtHoverPoint(_ point: CGPoint) -> NSTextAttachment? { let convertedPoint = convert(point, from: window) let charIndex = layoutManager.characterIndex(for: convertedPoint, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil) guard charIndex < textStorage.length else { return nil } let attributes = textStorage.attributes(at: charIndex, effectiveRange: nil) return attributes[.attachment] as? NSTextAttachment } // MARK: UIPointerInteractionDelegate func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? { guard let hoverPoint = region.location, getAttachmentAtHoverPoint(hoverPoint) != nil else { return nil // 非附件区域用默认指针 } // 创建圆形指针,半径可根据需求调整(Apple Notes约为12) let circleShape = UIPointerShape.circular(radius: 12) return UIPointerStyle(effect: .highlight, shape: circleShape) } }
方案二:给单个附件的ContentView添加指针交互(精准控制)
如果你的NSTextAttachment使用了自定义contentView,可以直接给该视图绑定指针交互:
// 创建带自定义视图的文本附件 let attachment = NSTextAttachment() let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) contentView.backgroundColor = .lightGray attachment.contentView = contentView // 给ContentView添加指针交互 let pointerInteraction = UIPointerInteraction(delegate: self) contentView.addInteraction(pointerInteraction) // 实现代理方法返回圆形样式 extension YourViewController: UIPointerInteractionDelegate { func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? { let circleShape = UIPointerShape.circular(radius: 12) return UIPointerStyle(effect: .highlight, shape: circleShape) } }
注意事项
- 确保UITextView的
userInteractionEnabled属性为true(默认开启) - 方案一中的坐标转换要准确,避免误判悬停区域
- 圆形指针的半径可根据附件大小自行调整,匹配视觉需求
内容的提问来源于stack exchange,提问作者a.wip
相关产品推荐
相关产品推荐

