如何调用UITextView中NSDataDetector不具备的额外文本检测能力?
在Swift中复用UITextView的增强文本检测能力
是的,你可以通过两种方式复用UITextView的增强文本检测能力:让它返回已检测内容,或者间接调用其底层检测逻辑——因为UITextView的额外检测(货运追踪号、物理单位等)是系统内部实现的,没有直接暴露API,但可以通过以下方法实现需求:
方法一:让UITextView返回已检测内容
你可以创建一个非可视化的UITextView,传入目标文本后,通过其NSLayoutManager获取所有检测结果。UITextView在布局过程中会自动执行系统级的增强文本检测,包括NSDataDetector不支持的货运追踪号、物理单位等类型。
示例代码
import UIKit func getDetectedTextResults(from inputText: String) -> [NSTextCheckingResult] { let textView = UITextView() textView.text = inputText // 强制触发文本布局与检测 textView.layoutManager.ensureLayout(for: textView.bounds) var detectedResults = [NSTextCheckingResult]() let fullRange = NSRange(location: 0, length: inputText.utf16.count) // 遍历所有检测结果 textView.layoutManager.enumerateTextCheckingResults(in: fullRange, types: NSTextCheckingResult.CheckingType.all.rawValue) { result, _, _ in if let validResult = result { detectedResults.append(validResult) } } return detectedResults } // 使用示例 let testText = "我的快递单号是1Z999AA10123456784,包裹重量为3.5kg" let results = getDetectedTextResults(from: testText) for result in results { let matchedText = (testText as NSString).substring(with: result.range) switch result.resultType { case .shippingTrackingNumber: print("检测到货运追踪号:\(matchedText)") case .unit: print("检测到物理单位:\(matchedText)") case .link, .address, .phoneNumber: print("检测到常规类型:\(matchedText)") default: break } }
关键说明
- 创建的UITextView不需要添加到视图层级,仅用于复用其检测逻辑。
- 调用
ensureLayout(for:)是为了确保UITextView完成文本布局和检测,避免返回空结果。 - 检测结果包含
NSTextCheckingResult,可以通过resultType区分不同的检测类型(如shippingTrackingNumber、unit)。
方法二:间接调用底层增强检测机制
UITextView的检测逻辑依赖于系统内置的文本检查器,没有直接暴露的API,但上述方法本质上就是在间接调用这个底层机制——通过UITextView的NSLayoutManager触发系统的增强文本检测,无需额外实现复杂的正则或检测逻辑。
内容的提问来源于stack exchange,提问作者Gareth Simpson
相关产品推荐
相关产品推荐

