Swift开发iOS相机App点击Use Photo按钮后CameraView冻结问题
iOS 相机应用拍照后CameraView冻结问题排查
问题现象
已授权相册访问权限的前提下,用户完成拍照点击「Use Photo」按钮时,拍摄的照片可正常保存至系统相册,但CameraView会完全冻结无响应。
相关代码片段
ContentView 代码
struct ContentView: View { var body: some View { CameraView() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
CameraView 中 Coordinator 部分代码
extension CameraView { class Coordinator : NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var parent: CameraView init(_ parent: CameraView) { self.parent = parent } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { fatalError("Cancel button pressed!") } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) CustomizeView() } } } }
「Use Photo」按钮对应控制逻辑
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) // 执行到此处后CameraView冻结 }
问题根因
- 核心冻结原因:实现
UIImagePickerControllerDelegate的选择完成回调后,没有手动调用dismiss关闭当前弹出的UIImagePicker控制器。系统不会自动移除该控制器,保存照片完成后picker仍覆盖在界面顶层拦截所有交互,表现为CameraView完全无响应。 - 附加逻辑错误:
- 取消回调中直接调用
fatalError,会导致用户点击取消按钮时应用直接崩溃。 - 代理回调中直接初始化
CustomizeView()属于错误写法,SwiftUI的View是值类型,直接初始化不会触发正确的页面跳转逻辑,反而会导致UI状态混乱。
- 取消回调中直接调用
修复方案
- 在
didFinishPickingMediaWithInfo回调中,先执行picker.dismiss(animated: true)关闭图片选择器,解除UI交互阻塞。 - 移除取消回调中的
fatalError,替换为正常dismiss picker的逻辑,避免点取消崩溃。 - 给CameraView添加绑定的状态变量,通过状态控制CustomizeView的弹出,不要在代理回调中直接初始化SwiftUI视图。
修复后代码参考
CameraView 状态定义
struct CameraView: View { @State private var capturedImage: UIImage? @State private var isShowCustomizePage = false var body: some View { // 原有相机页面逻辑 .sheet(isPresented: $isShowCustomizePage) { if let img = capturedImage { CustomizeView(editImage: img) } } } }
修复后的 Coordinator 代理实现
extension CameraView { class Coordinator : NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var parent: CameraView init(_ parent: CameraView) { self.parent = parent } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // 先关闭picker,解决冻结问题 picker.dismiss(animated: true) guard let image = info[.originalImage] as? UIImage else { return } UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) // 赋值后通过状态触发页面跳转 parent.capturedImage = image parent.isShowCustomizePage = true } } }
内容的提问来源于stack exchange,提问作者Aadish123
相关产品推荐
相关产品推荐

