iOS 自定义键盘扩展如何获取完整选中文本?
结论
如果 textDocumentProxy.selectedText 在当前宿主输入框中只返回部分内容,键盘扩展通常无法通过移动光标,再拼接 documentContextBeforeInput 和 documentContextAfterInput,可靠地还原完整选区。UITextDocumentProxy 提供的是文本输入上下文代理,不是读取宿主应用完整文档的接口。Apple 将 selectedText 定义为当前选中的文本,将前后文定义为插入点周围的文本。UITextDocumentProxy 文档 自定义键盘中的文本交互
先检查代理返回值
可以先读取选区,并将 nil 或空字符串视为当前没有可用的选中文本:
if let selectedText = textDocumentProxy.selectedText,
!selectedText.isEmpty {
// 使用 selectedText
} else {
// 当前代理没有提供选中文本
}
如果返回的字符串只有部分内容,不建议通过拼接光标移动前后的上下文来还原“完整选区”。这些上下文相对于当前插入点返回;移动光标可能改变插入点或选区状态,也无法保证宿主输入框会提供被截断的文本。你描述的结果说明,在该输入框和当前状态下,代理没有提供预期的完整选区。
需要完整文本时的方案
如果你也控制宿主应用,可以在应用的文本控件中读取选区,并由应用处理后续功能。例如,宿主应用使用 UITextView 时,可以在应用侧根据选区范围取出文本:
if let range = textView.selectedTextRange,
let selectedText = textView.text(in: range) {
// 在宿主应用侧处理完整选中文本
}
如果键盘扩展运行在其他应用中,就无法直接访问该应用的 UITextView 或完整文档。可以让用户复制文本,再粘贴到键盘提供的操作流程中;也可以通过宿主应用提供的分享或选择文本入口处理。具体能否使用,取决于宿主应用是否支持这些交互。
注意事项
Apple 对 selectedText 的接口说明是返回当前选中文本,但没有承诺所有宿主输入控件都会提供相同范围的上下文,也没有提供补全截断内容的机制。因此,selectedText 应视为代理当前提供的选区结果。宿主只暴露部分内容时,键盘扩展没有通用且可靠的恢复办法。
备注:内容仅供参考。
