4

I tried to make a SwiftUI class that conforms to UIViewRepresentable and implements makeUIView and updateUIView. But not able to complete it.Here is code :

Code:

struct ImagePicker : UIViewRepresentable {

@Binding var image: UIImage

class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @Binding var image: UIImage

    init(image: Binding<UIImage>) {
        $image = image
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {


        if let possibleImage = info[.editedImage] as? UIImage {
            image = possibleImage
        } else if let possibleImage = info[.originalImage] as? UIImage {
            image = possibleImage
        } else {

        }
    }
}

func makeCoordinator() -> Coordinator {
    return Coordinator(image: $image)
}

func makeUIView(context: UIViewRepresentableContext<ImagePicker>) -> UIImageView {
    let imageview = UIImageView()
    let picker = UIImagePickerController()
    picker.delegate = context.coordinator
    return imageview
}

func updateUIView(_ uiView: UIImageView,
                  context: UIViewRepresentableContext<ImagePicker>) {
    uiView.image = image
}

}

I tried imagePicker as control but unable to use.

Kampai
  • 22,335
  • 20
  • 91
  • 93
Monil Gandhi
  • 99
  • 1
  • 10
  • 1
    I *had* a working version of `UIImagePickerController`. Looking at your code, you're close. But. First off, what do you mean by "it isn't working". (More details would be helpful.) Next, my version is based off of the accepted answer to this question: https://stackoverflow.com/questions/56515871/how-to-open-the-imagepicker-in-swiftui BUT FINALLY - sorry for the shouting - my version, that version, and I'm guessing your version are all broken in beta 4, which was released three days ago. What version of everything are you running? –  Jul 19 '19 at 12:07
  • Thanks for reply. Your answer is worked for me. – Monil Gandhi Jul 23 '19 at 09:28

2 Answers2

10

I am using presentationMode here, to check for the view that is it presenting or not?

By using this you can dismiss() the UIImagePickerController.

Sample code for SwiftUI preview:

import SwiftUI

struct ContentView: View {

    @State var isShowPicker: Bool = false
    @State var image: Image? = Image("placeholder")

    var body: some View {
        NavigationView {
            ZStack {
                VStack {
                    image?
                        .resizable()
                        .scaledToFit()
                        .frame(height: 320)
                    Button(action: {
                        withAnimation {
                            self.isShowPicker.toggle()
                        }
                    }) {
                        Image(systemName: "photo")
                            .font(.headline)
                        Text("IMPORT").font(.headline)
                    }.foregroundColor(.black)
                    Spacer()
                }
            }
            .sheet(isPresented: $isShowPicker) {
                ImagePicker(image: self.$image)
            }
            .navigationBarTitle("Pick Image")
        }
    }
}


struct ImagePicker: UIViewControllerRepresentable {

    @Environment(\.presentationMode)
    var presentationMode

    @Binding var image: Image?

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

        @Binding var presentationMode: PresentationMode
        @Binding var image: Image?

        init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) {
            _presentationMode = presentationMode
            _image = image
        }

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

        }

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

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(presentationMode: presentationMode, image: $image)
    }

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

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

    }

}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ContentView()
        }
    }
}
Kampai
  • 22,335
  • 20
  • 91
  • 93
1

Pls try This one

Code:

import SwiftUI

struct OpenGallary: UIViewControllerRepresentable {

    let isShown: Binding<Bool>
    let image: Binding<Image?>

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

        let isShown: Binding<Bool>
        let image: Binding<Image?>

        init(isShown: Binding<Bool>, image: Binding<Image?>) {
            self.isShown = isShown
            self.image = image
        }

        func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            self.image.wrappedValue = Image(uiImage: uiImage)
            self.isShown.wrappedValue = false
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            isShown.wrappedValue = false
        }

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(isShown: isShown, image: image)
    }

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

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

    }
}

the picker is displayed right on top of the view, without transition the selected image appears without any sort of animation, and replaces the Show image picker button

After that create display view in which you can call show this imagePicker

struct ContentView: View {

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

    var body: some View {
        ZStack {
            VStack {
                Button(action: {
                    withAnimation {
                        self.showImagePicker.toggle()
                    }
                }) {
                    Text("Show image picker")
                }
                image?.resizable().frame(width: 100, height: 100)
            }
            if (showImagePicker) {
                OpenGallary(isShown: $showImagePicker, image: $image)
            }
        }
    }
}
NøBi Mac
  • 369
  • 2
  • 11
Raj Aryan
  • 152
  • 1
  • 11