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
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