首页 > 解决方案 > 如何在 SwiftUI 中打开 ImagePicker?

问题描述

我需要使用 SwiftUI 在我的应用程序中打开一个图像选择器,我该怎么做?

我考虑过使用UIImagePickerController,但我不知道如何在 SwiftUI 中做到这一点。

标签: iosswiftuiimagepickercontrollerswiftui

解决方案


您需要包装UIImagePickerController一个实现UIViewControllerRepresentable.

有关更多信息UIViewControllerRepresentable,请查看这个惊人的 WWDC 2019 演讲:

集成 SwiftUI

struct ImagePicker: UIViewControllerRepresentable {

    @Environment(\.presentationMode)
    private var presentationMode

    let sourceType: UIImagePickerController.SourceType
    let onImagePicked: (UIImage) -> Void

    final class Coordinator: NSObject,
    UINavigationControllerDelegate,
    UIImagePickerControllerDelegate {

        @Binding
        private var presentationMode: PresentationMode
        private let sourceType: UIImagePickerController.SourceType
        private let onImagePicked: (UIImage) -> Void

        init(presentationMode: Binding<PresentationMode>,
             sourceType: UIImagePickerController.SourceType,
             onImagePicked: @escaping (UIImage) -> Void) {
            _presentationMode = presentationMode
            self.sourceType = sourceType
            self.onImagePicked = onImagePicked
        }

        func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            onImagePicked(uiImage)
            presentationMode.dismiss()

        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            presentationMode.dismiss()
        }

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(presentationMode: presentationMode,
                           sourceType: sourceType,
                           onImagePicked: onImagePicked)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController,
                                context: UIViewControllerRepresentableContext<ImagePicker>) {

    }

}

这是一个简单的视图来测试它:

  • 选择器显示在工作表中
  • 所选图像出现时没有任何动画,并替换Show image picker按钮
struct ContentView: View {

    @State var showImagePicker: Bool = false
    @State var image: Image? = nil

    var body: some View {
        ZStack {
            VStack {
                Button(action: {
                    self.showImagePicker.toggle()
                }) {
                    Text("Show image picker")
                }
                image?.resizable().frame(width: 100, height: 100)
            }
            .sheet(isPresented: $showImagePicker) {
                ImagePicker(sourceType: .photoLibrary) { image in
                    self.image = Image(uiImage: image)
                }
            }
        }
    }
}

我希望这有助于作为一个起点!

SwiftUI我敢肯定,一旦测试版结束,Apple 会让这件事变得更容易。

在此处输入图像描述

在 Xcode 11.4 上测试

错误:

  • @JAHelia 在sourceType不是相机时在选择器上发现了一个错误。您将无法向下拖动工作表 - 我还没有找到解决方案。

推荐阅读