How to open the ImagePicker in SwiftUI?

后端 未结 8 1305
生来不讨喜
生来不讨喜 2020-11-29 23:53

I need to open the ImagePicker in my app using SwiftUI, how can I do that?

I thought about using the UIImagePickerController, but I don\'t know how to do that in Swi

8条回答
  •  醉话见心
    2020-11-30 00:23

    Here's a version that works in Xcode 11 beta 4.

    It uses a BindableObject singleton (ImagePicker.shared) with two properties: .view and .image.

    See usage below (ImagePickerTestView)

    import SwiftUI
    import Combine
    
    final class ImagePicker : BindableObject {
    
        static let shared : ImagePicker = ImagePicker()
    
        private init() {}  //force using the singleton: ImagePicker.shared
    
        let view = ImagePicker.View()
        let coordinator = ImagePicker.Coordinator()
    
        // Bindable Object part
        let willChange = PassthroughSubject()
    
        @Published var image: Image? = nil {
            didSet {
                if image != nil {
                    willChange.send(image)
                }
            }
        }
    }
    
    
    extension ImagePicker {
    
        class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
            // UIImagePickerControllerDelegate
            func imagePickerController(_ picker: UIImagePickerController,
                                       didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
                let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
                ImagePicker.shared.image = Image(uiImage: uiImage)
                picker.dismiss(animated:true)
            }
    
            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                picker.dismiss(animated:true)
            }
        }
    
    
        struct View: UIViewControllerRepresentable {
    
            func makeCoordinator() -> Coordinator {
                ImagePicker.shared.coordinator
            }
    
            func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIImagePickerController {
                let picker = UIImagePickerController()
                picker.delegate = context.coordinator
                return picker
            }
    
            func updateUIViewController(_ uiViewController: UIImagePickerController,
                                        context: UIViewControllerRepresentableContext) {
    
            }
    
        }
    
    }
    
    
    struct ImagePickerTestView: View {
    
        @State var showingPicker = false
    
        @State var image : Image? = nil
        // you could use ImagePicker.shared.image directly
    
        var body: some View {
            VStack {
                Button("Show image picker") {
                    self.showingPicker = true
                }
    
                image?
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 300)
    
            }.sheet(isPresented: $showingPicker,
                    onDismiss: {
                        // do whatever you need here
                    }, content: {
                        ImagePicker.shared.view
                    })
            .onReceive(ImagePicker.shared.$image) { image in
                // This gets called when the image is picked.
                // sheet/onDismiss gets called when the picker completely leaves the screen
                self.image = image
            }
        }
    
    }
    
    #if DEBUG
    struct ImagePicker_Previews : PreviewProvider {
    
        static var previews: some View {
            ImagePickerTestView()
        }
    }
    #endif
    

提交回复
热议问题