Good day,
I am new to ios development and trying to make an image picker to print out the path of the images to eventually store in a json file but I keep getting this error
Cannot convert value of type 'Binding' to expected argument type 'Binding'
Here is the code that I am busy with.
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
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 images = info[.originalImage] as? [UIImage] {
for image in images {
print(image)
}
}
parent.$presentationMode.wrappedValue.dismiss()
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
@Binding var presentationMode: PresentationMode
@Binding var images: [UIImage]
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = .photoLibrary
picker.allowsEditing = false
picker.modalPresentationStyle = .fullScreen
picker.mediaTypes = ["public.image"]
picker.videoQuality = .typeHigh
picker.videoMaximumDuration = TimeInterval(30)
picker.modalPresentationStyle = .popover
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
uiViewController.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 0, height: 0))
}
}
struct ImagePickerView: View {
@State private var showImagePicker = false
@State private var images = [UIImage]()
var body: some View {
Button("Select Images") {
self.showImagePicker = true
}
.sheet(isPresented: $showImagePicker, onDismiss: {
self.showImagePicker = false
}, content: {
ImagePicker(presentationMode: self.$showImagePicker, images: self.$images)
})
}
}
struct ImagePickerViewPreviews: PreviewProvider {
static var previews: some View {
ImagePickerView()
}
}
There are a couple of issues:
Binding<Bool>
to a Binding<PresentationMode>
[UIImage]
instead of UIImage
You actually don't need the PresentationMode
at all -- you can just use the single Bool
binding for showImagePicker
since all you're doing is trying to effect whether the view is shown or not.
See comments for the changed lines:
struct ImagePicker: UIViewControllerRepresentable {
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// <-- Here
if let image = info[.originalImage] as? UIImage {
self.parent.images = [image]
}
parent.showImagePicker = false // <-- Here
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
@Binding var showImagePicker: Bool // <-- Here
@Binding var images: [UIImage]
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = .photoLibrary
picker.allowsEditing = false
picker.modalPresentationStyle = .fullScreen
picker.mediaTypes = ["public.image"]
picker.videoQuality = .typeHigh
picker.videoMaximumDuration = TimeInterval(30)
picker.modalPresentationStyle = .popover
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
uiViewController.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 0, height: 0))
}
}
struct ImagePickerView: View {
@State private var showImagePicker = false
@State private var images = [UIImage]()
var body: some View {
Button("Select Images") {
self.showImagePicker = true
}
// <-- Here
.sheet(isPresented: $showImagePicker) {
ImagePicker(showImagePicker: $showImagePicker, images: $images)
}
.onChange(of: images) { newValue in
print("Images: ", newValue)
}
}
}