SwiftUI中的ImagePicker

时间:2019-12-07 14:47:19

标签: swift uiimagepickercontroller swiftui

我正在尝试在this tutorial之后在SwiftUI中创建一个图像选择器。基本上,这种想法是,当用户点击屏幕上的灰色矩形时,会出现一个图像选择器。当他们选择图像时,该图像将导入到灰色矩形中。

问题是,当我运行代码时,出现以下错误: Thread 1: Fatal error: Reading Environment<Binding<PresentationMode>> outside View.body

它出现在“图像选择器结构”中的parent.presentationMode.wrappedValue.dismiss()行上。

我的代码如下:

图像选择器


struct ImagePicker: UIViewControllerRepresentable {

  @Environment(\.presentationMode) var presentationMode
  @Binding var image: UIImage?

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker

        init(_ parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.image = uiImage
            }

        parent.presentationMode.wrappedValue.dismiss()
        }     
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }


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

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

    }
}

内容视图

import SwiftUI

struct ContentView: View {

    @State private var image: Image?
    @State private var showingImagePicker = false
    @State private var inputImage: UIImage?


    var body: some View {
     NavigationView {
             ZStack {
                 Rectangle()
                     .fill(Color.secondary)

                 if image != nil {
                     image?
                         .resizable()
                         .scaledToFit()
                 } else {
                     Text("Tap to select a picture")
                 }
             }
             .onTapGesture {
                 self.showingImagePicker = true
             }


        .sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
            ImagePicker(image: self.$inputImage)
        }
     }
    }

    func loadImage() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
    }

}

类似于推荐的解决方案here,我尝试在Image Picker Struct中将@Environment(\.presentationMode) var presentationMode替换为@Binding var isPresented: Bool,并用parent.presentationMode.wrappedValue.dismiss()替换了麻烦的行parent.isPresented = false

但是,这导致了一个不同的问题-关闭工作表时图像没有加载(我想是因为我没有在任何地方调用dismiss()方法)。

我对Swift和编码还很陌生,因此,如果我在任何地方的解释都更简洁,可以随时进行更正,则深表歉意。

1 个答案:

答案 0 :(得分:2)

好的,看起来您正在使用13.1进行测试->更新到13.2-可以正常工作