SwiftUI中点击Button如何直接调用UIAction.captureTextFromCamera提取实况文本
实现方案
核心逻辑:UIAction.captureTextFromCamera 确实要求必须关联到Menu才能正常触发,我们可以通过添加完全隐藏的Menu、点击按钮时主动触发Menu内的动作来实现需求,无需用户手动点击Menu选项。
步骤1:创建文本接收响应器
首先创建承接实况文本返回结果的响应器类,遵循系统要求的UIKeyInput协议:
import UIKit class CameraTextCaptureResponder: UIResponder, UIKeyInput { var onTextCaptured: (String) -> Void init(onTextCaptured: @escaping (String) -> Void) { self.onTextCaptured = onTextCaptured super.init() } var hasText: Bool { true } func insertText(_ text: String) { onTextCaptured(text) } func deleteBackward() {} override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { if action == #selector(captureTextFromCamera(_:)) { return true } return super.canPerformAction(action, withSender: sender) } @objc func captureTextFromCamera(_ sender: Any?) {} }
步骤2:实现SwiftUI视图逻辑
通过隐藏Menu+按钮主动触发的方式实现直接调用:
import SwiftUI struct LiveTextDemoView: View { @State private var text = "" @State private var triggerHiddenMenu = false // 初始化响应器,接收返回的文本 private let captureResponder = CameraTextCaptureResponder { newText in DispatchQueue.main.async { text = newText } } var body: some View { VStack(spacing: 30) { Text(text) .padding() .border(.gray.opacity(0.3), cornerRadius: 8) Button { // 点击按钮直接触发隐藏Menu内的动作 triggerHiddenMenu = true } label: { Label("提取实况文本", systemImage: "camera.viewfinder") .padding() .background(.blue) .foregroundColor(.white) .cornerRadius(8) } // 挂载完全隐藏的Menu .background { Menu(isPresented: $triggerHiddenMenu) { Button(action: { let action = UIAction.captureTextFromCamera(responder: captureResponder, identifier: nil) action.perform(with: nil) }) { EmptyView() } } label: { EmptyView() } .menuStyle(.borderlessButton) .menuIndicator(.hidden) .opacity(0) .allowsHitTesting(false) } } .padding() } }
注意事项
- 该功能仅支持iOS 16及以上系统
- 必须在项目Info.plist中添加
NSCameraUsageDescription键,填写相机使用权限说明,否则调用时会直接崩溃 - 捕获到的文本回调默认在非主线程返回,更新UI时需要手动切到主线程
内容的提问来源于stack exchange,提问作者Underthestars-zhy
相关产品推荐
相关产品推荐

