SwiftUI中使用UIImagePicker选相册图片无法捕获用户操作如何解决
解决方案
你的代码核心问题是没有遵循UIViewControllerRepresentable的标准实现规范,直接将ChooseImageView实例本身设置为UIImagePickerController的代理,SwiftUI不会持有该实例作为代理的引用,因此代理方法无法被触发。你需要使用SwiftUI要求的Coordinator作为代理对象,同时调整选择器的调用方式。
修改后的完整实现
1. 重写ChooseImageView
struct ChooseImageView: UIViewControllerRepresentable { // 回传选中的图片到父视图 @Binding var selectedImage: UIImage? // 控制选择器的展示/关闭状态 @Binding var isPresented: Bool // 生成Coordinator作为代理载体 func makeCoordinator() -> Coordinator { Coordinator(parent: self) } func makeUIViewController(context: Context) -> UIImagePickerController { let libraryPicker = UIImagePickerController() libraryPicker.sourceType = .photoLibrary // 把Coordinator设为代理,而非self libraryPicker.delegate = context.coordinator return libraryPicker } func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {} // 代理方法全部放到Coordinator中实现 class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { let parent: ChooseImageView init(parent: ChooseImageView) { self.parent = parent } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // 这里的print会正常输出 print("I got a change") // 取出选中的原图 if let image = info[.originalImage] as? UIImage { parent.selectedImage = image } // 关闭选择器 parent.isPresented = false } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { parent.isPresented = false } } }
2. 调整父视图PhotoPage的实现
相册选择器通常以弹窗形式弹出,不要直接嵌入到普通视图层级中:
struct PhotoPage: View { // 存储用户选中的图片 @State private var selectedImage: UIImage? // 控制选择器是否弹出 @State private var showImagePicker = false var body: some View { VStack(alignment: .center, spacing: 20) { // 选中后展示图片 if let image = selectedImage { Image(uiImage: image) .resizable() .scaledToFit() .frame(height: 200) } // 点击按钮唤起相册选择器 Button("从相册选择照片") { showImagePicker = true } } .sheet(isPresented: $showImagePicker) { ChooseImageView(selectedImage: $selectedImage, isPresented: $showImagePicker) } } }
注意事项
- 你需要在项目的
Info.plist中添加相册访问权限说明,添加key为Privacy - Photo Library Usage Description,value填写权限用途描述,比如"需要访问相册以选择照片",否则App会在访问相册时直接崩溃。 - 若你的App最低支持iOS 14及以上版本,可以直接使用SwiftUI原生的
PhotosPicker组件,不需要自行桥接UIKit,实现逻辑更简单。
内容的提问来源于stack exchange,提问作者Agricola
相关产品推荐
相关产品推荐

