SwiftUI中UIImagePickerController自动拍照功能失效问题
解决SwiftUI中UIImagePickerController自动拍照的问题
你的问题核心是调用takePicture()的时机不对——在updateUIViewController阶段,UIImagePickerController的相机界面还未完全初始化完成,此时调用拍照方法不会生效,也无法触发代理回调。下面是修正方案:
修正思路
利用UIViewController的生命周期方法,在相机界面完全呈现后(即viewDidAppear关联的导航控制器回调阶段)调用takePicture(),同时通过标记位避免重复触发自动拍照。
修改后的完整代码
import Foundation import SwiftUI import UIKit import MobileCoreServices class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @Binding var isShown: Bool @Binding var image: UIImage? // 标记是否需要执行自动拍照 var shouldAutoCapture: Bool = true init(isShown: Binding<Bool>, image: Binding<UIImage?>) { _isShown = isShown _image = image } // 监听picker的界面呈现完成事件 func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { guard let picker = viewController as? UIImagePickerController, shouldAutoCapture else { return } // 相机界面已完全加载,执行自动拍照 picker.takePicture() // 标记为已执行,避免重复拍照 shouldAutoCapture = false } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { print("拍照成功,进入回调") if let uiImage = info[.originalImage] as? UIImage { image = uiImage } isShown = false picker.dismiss(animated: true) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { isShown = false } } struct ImagePicker: UIViewControllerRepresentable { @Binding var isShown: Bool @Binding var image: UIImage? func makeCoordinator() -> ImagePickerCoordinator { ImagePickerCoordinator(isShown: $isShown, image: $image) } func makeUIViewController(context: Context) -> UIImagePickerController { let picker = UIImagePickerController() picker.delegate = context.coordinator picker.sourceType = .camera picker.cameraCaptureMode = .photo picker.allowsEditing = false picker.showsCameraControls = false return picker } func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) { // 当isShown从false变为true时,重置自动拍照标记 if isShown { context.coordinator.shouldAutoCapture = true } } }
关键说明
- 生命周期监听:通过
UINavigationControllerDelegate的navigationController(_:didShow:animated:)方法,确保相机界面完全加载后再执行拍照操作。 - 避免重复拍照:用
shouldAutoCapture标记位控制只自动拍一次,每次isShown切换为true时重置该标记,支持多次触发相机自动拍照。 - 安全处理:将原代码中强制解包
UIImage改为可选绑定,避免因数据异常导致崩溃。
额外注意事项
- 必须在
Info.plist中添加相机权限描述(NSCameraUsageDescription),否则相机无法正常启动。 - 如果需要自定义拍照延迟或重复拍照逻辑,可在
navigationController(_:didShow:animated:)中添加DispatchQueue延迟执行,或调整shouldAutoCapture的重置时机。
内容的提问来源于stack exchange,提问作者Manan Vij
相关产品推荐
相关产品推荐

