You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift如何通过按钮点击触发TextField长按唤起的Scan Text功能

实现方案

iOS 15.4以上系统完全可以实现,直接复用长按唤起的同款原生Scan Text能力,不需要自己编写OCR识别逻辑,具体做法如下:

  • 系统给所有文本输入控件默认内置了扫描文本的触发动作,长按弹出的菜单选项本质就是调用的这个内置动作,只需要在按钮点击时主动触发该动作即可,不涉及私有API,可正常通过App Store审核。
  • 实现时通过视图层级找到当前激活的TextField实例,主动调用对应扫描方法即可,最终弹出的扫描界面、识别逻辑、文本填充效果和长按唤起的完全一致,没有体验差异。

完整代码

首先编写一个查找当前激活输入框的扩展:

import SwiftUI
import UIKit

extension UIApplication {
    func getActiveTextField() -> UITextField? {
        guard let windowScene = connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
              let rootVC = windowScene.windows.first(where: \.isKeyWindow)?.rootViewController else {
            return nil
        }
        return findTextField(in: rootVC.view)
    }
    
    private func findTextField(in view: UIView) -> UITextField? {
        if let textField = view as? UITextField, textField.isFirstResponder {
            return textField
        }
        for subview in view.subviews {
            if let target = findTextField(in: subview) {
                return target
            }
        }
        return nil
    }
}

替换原有布局代码,补充按钮点击逻辑:

HStack{
    TextField("Service Name", text: $serviceFieldName)
    Button("Scan"){
        guard let activeTF = UIApplication.shared.getActiveTextField() else { return }
        activeTF.becomeFirstResponder()
        // 延迟0.1秒触发,等待响应链状态稳定
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            activeTF.perform(Selector(("scanText:")))
        }
    }
}
.padding()

注意事项:

  1. 低于iOS 15.4的系统没有内置该扫描功能,需要自行接入Vision框架实现文字识别
  2. 记得在Info.plist中添加相机权限描述NSCameraUsageDescription,否则调用扫描时会直接崩溃
  3. iOS 16及以上版本可以直接使用官方公开的UIScanTextInteraction类主动触发扫描,稳定性更强,上述写法是兼容更低版本的最简实现
  • 如果触发无响应,优先检查TextField是否正常成为第一响应者,必须进入输入状态才能正常调出扫描面板

内容的提问来源于stack exchange,提问作者fs_tigre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:15:34