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
Based on @user:2890168 I made a version that:
UIImage
instead of Image
.sheet
to present the ImagePicker
. ActionSheet
to help users to remove or change the image.struct LibraryImage: View {
@State var showAction: Bool = false
@State var showImagePicker: Bool = false
@State var uiImage: UIImage? = nil
var sheet: ActionSheet {
ActionSheet(
title: Text("Action"),
message: Text("Quotemark"),
buttons: [
.default(Text("Change"), action: {
self.showAction = false
self.showImagePicker = true
}),
.cancel(Text("Close"), action: {
self.showAction = false
}),
.destructive(Text("Remove"), action: {
self.showAction = false
self.uiImage = nil
})
])
}
var body: some View {
VStack {
if (uiImage == nil) {
Image(systemName: "camera.on.rectangle")
.accentColor(Color.App.purple)
.background(
Color.App.gray
.frame(width: 100, height: 100)
.cornerRadius(6))
.onTapGesture {
self.showImagePicker = true
}
} else {
Image(uiImage: uiImage!)
.resizable()
.frame(width: 100, height: 100)
.cornerRadius(6)
.onTapGesture {
self.showAction = true
}
}
}
.sheet(isPresented: $showImagePicker, onDismiss: {
self.showImagePicker = false
}, content: {
ImagePicker(isShown: self.$showImagePicker, uiImage: self.$uiImage)
})
.actionSheet(isPresented: $showAction) {
sheet
}
}
}
The default body
of LibraryImage
is an Image
that shows a camera icon that is tappable by the users.
On tap event, the image picker is shown with a sheet
modifier. After the image selection, the LibraryImage
body is recomputed and now shows the Image
defined in else statement (because uiImage
property now contains the image picked by the user).
Now, on tap event the ActionSheet
is shown.
The edited image picker:
struct ImagePicker: UIViewControllerRepresentable {
@Binding var isShown: Bool
@Binding var uiImage: UIImage?
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@Binding var isShown: Bool
@Binding var uiImage: UIImage?
init(isShown: Binding, uiImage: Binding) {
_isShown = isShown
_uiImage = uiImage
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let imagePicked = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
uiImage = imagePicked
isShown = false
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
isShown = false
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(isShown: $isShown, uiImage: $uiImage)
}
func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController,
context: UIViewControllerRepresentableContext) {
}
}
default behaviour: