SwiftUI+UIImagePickerController:相机开启时保持闪光灯常亮
实现UIImagePickerController闪光灯常亮
问题核心:直接在makeUIViewController中操作闪光灯会失效,因为此时相机会话尚未完全初始化,系统后续会重置闪光灯状态,导致短暂亮起后熄灭。以下是修改方案:
步骤1:自定义UIImagePickerController子类
创建子类并重写viewDidAppear方法,在相机界面完全加载后开启闪光灯常亮:
class CustomImagePickerController: UIImagePickerController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return } do { try device.lockForConfiguration() try device.setTorchModeOn(level: 1.0) device.unlockForConfiguration() } catch { print("开启闪光灯失败: \(error)") } } }
步骤2:修改ImagePicker结构体
将原有的UIImagePickerController替换为自定义子类,移除无效的toggleFlash调用:
struct ImagePicker: UIViewControllerRepresentable { @Binding var isShown: Bool @Binding var image: UIImage? @Binding var didTapCapture: Bool func updateUIViewController(_ uiViewController: CustomImagePickerController, context: Context) { uiViewController.showsCameraControls = false if didTapCapture { uiViewController.takePicture() didTapCapture = false } } func makeCoordinator() -> ImagePickerCoordinator { ImagePickerCoordinator(isShown: $isShown, image: $image) } func makeUIViewController(context: Context) -> CustomImagePickerController { let picker = CustomImagePickerController() picker.delegate = context.coordinator picker.sourceType = .camera picker.showsCameraControls = false picker.modalPresentationStyle = .fullScreen return picker } }
步骤3:在Coordinator中处理闪光灯关闭
在相机关闭时(拍照完成或取消)关闭闪光灯,避免资源占用:
class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @Binding var isShown: Bool @Binding var image: UIImage? init(isShown: Binding<Bool>, image: Binding<UIImage?>) { _isShown = isShown _image = image } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { let uiImage = info[.originalImage] as! UIImage image = uiImage closeFlash() isShown = false } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { closeFlash() isShown = false } private func closeFlash() { guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return } do { try device.lockForConfiguration() device.torchMode = .off device.unlockForConfiguration() } catch { print("关闭闪光灯失败: \(error)") } } }
原理说明
viewDidAppear是相机界面完全加载、会话启动后的回调,此时设置闪光灯状态不会被系统重置。- 自定义子类确保闪光灯逻辑与相机生命周期绑定,避免时机错误。
- 关闭相机时主动关闭闪光灯,符合资源管理规范。
内容的提问来源于stack exchange,提问作者Manan Vij
相关产品推荐
相关产品推荐

