You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中打开ImagePicker?含UIImagePickerController实现疑问

在SwiftUI中实现图片选择器(基于UIImagePickerController)

嘿,我刚好在SwiftUI项目里折腾过这个,用UIImagePickerController完全可行——核心就是把UIKit的这个控制器用UIViewControllerRepresentable包装成SwiftUI能直接用的组件,下面给你一步步拆解:

第一步:包装UIImagePickerController成SwiftUI组件

我们需要写一个遵循UIViewControllerRepresentable的结构体,把UIImagePickerController的逻辑封装进去,同时通过Binding把选中的图片传递回SwiftUI视图:

import SwiftUI
import UIKit

struct ImagePicker: UIViewControllerRepresentable {
    // 绑定用于传递选中的图片
    @Binding var selectedImage: UIImage?
    // 用Environment的dismiss来关闭picker
    @Environment(\.dismiss) private var dismiss
    
    // 选择来源:相册(photoLibrary)或相机(camera)
    let sourceType: UIImagePickerController.SourceType
    
    // 创建并配置UIImagePickerController实例
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        // 把Coordinator设为代理,处理选择/取消事件
        picker.delegate = context.coordinator
        // 如果需要支持图片编辑,打开下面这行
        // picker.allowsEditing = true
        return picker
    }
    
    // SwiftUI更新时的回调,这里不需要额外操作
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
    
    // 创建Coordinator,用于处理UIKit的代理方法
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    // Coordinator类:实现UIImagePickerController的代理协议
    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        let parent: ImagePicker
        
        init(_ parent: ImagePicker) {
            self.parent = parent
        }
        
        // 用户选中图片后的回调
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            // 如果开启了编辑,就取editedImage,否则取originalImage
            let imageKey: UIImagePickerController.InfoKey = picker.allowsEditing ? .editedImage : .originalImage
            if let image = info[imageKey] as? UIImage {
                parent.selectedImage = image
            }
            // 关闭picker
            parent.dismiss()
        }
        
        // 用户取消选择的回调
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            parent.dismiss()
        }
    }
}

第二步:在SwiftUI视图中使用ImagePicker

现在你可以像用普通SwiftUI组件一样调用这个ImagePicker,通常用sheet来弹出它:

struct ContentView: View {
    @State private var selectedImage: UIImage?
    @State private var showImagePicker = false
    // 存储选择的来源类型(相册/相机)
    @State private var pickerSourceType: UIImagePickerController.SourceType = .photoLibrary
    
    var body: some View {
        VStack(spacing: 20) {
            // 展示选中的图片
            if let image = selectedImage {
                Image(uiImage: image)
                    .resizable()
                    .scaledToFit()
                    .frame(height: 300)
                    .cornerRadius(12)
            } else {
                Text("还没选择图片哦")
                    .font(.title2)
                    .foregroundColor(.gray)
                    .padding(.vertical, 100)
            }
            
            HStack(spacing: 16) {
                Button("从相册选择") {
                    pickerSourceType = .photoLibrary
                    showImagePicker = true
                }
                .buttonStyle(.borderedProminent)
                
                Button("拍照") {
                    // 先检查相机是否可用(比如模拟器就没有相机)
                    if UIImagePickerController.isSourceTypeAvailable(.camera) {
                        pickerSourceType = .camera
                        showImagePicker = true
                    } else {
                        // 这里可以弹个提示告诉用户相机不可用
                        print("当前设备没有可用相机")
                    }
                }
                .buttonStyle(.borderedProminent)
                .tint(.green)
            }
        }
        .padding()
        // 弹出ImagePicker
        .sheet(isPresented: $showImagePicker) {
            ImagePicker(selectedImage: $selectedImage, sourceType: pickerSourceType)
        }
    }
}

关键注意事项

  • 权限配置:必须在Info.plist中添加权限描述,否则App会直接崩溃:
    • 相册权限:添加NSPhotoLibraryUsageDescription,值填类似“需要访问您的相册来选择图片”的描述
    • 相机权限:添加NSCameraUsageDescription,值填类似“需要访问您的相机来拍摄照片”的描述
  • 相机可用性检查:调用相机前一定要用UIImagePickerController.isSourceTypeAvailable(.camera)判断,避免在没有相机的设备上出错
  • 图片编辑支持:如果需要让用户编辑图片,只要在创建picker时设置picker.allowsEditing = true,然后从info[.editedImage]获取编辑后的图片就行

内容的提问来源于stack exchange,提问作者Shahar Melamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:05:36