I hope this is not a duplicate, but if it is can someone point me in the right direction. I tried different variation of the method and none of my breakpoints are stopping the flow.
PickerView
struct PickerView: UIViewControllerRepresentable {
@Binding var savedImage: Bool
@Binding var savedVideo: Bool
@Binding var video: AVAsset?
@Binding var image: UIImage?
@Environment(\.presentationMode) var isPresented
var sourceType: UIImagePickerController.SourceType?
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
if let type = self.sourceType {
imagePicker.sourceType = type
imagePicker.delegate = context.coordinator // confirming the delegate
imagePicker.mediaTypes = ["public.image", "public.movie"]
}
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
}
// Connecting the Coordinator class with this struct
func makeCoordinator() -> Coordinator {
return Coordinator(picker: self)
}
}
Coordinator
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var picker: PickerView
init(picker: PickerView) {
self.picker = picker
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let media = info[UIImagePickerController.InfoKey.mediaURL] as? NSURL {
self.picker.video = AVAsset(url: media.absoluteURL!)
self.picker.savedVideo = true
} else if let original = info[.originalImage] as? UIImage {
self.picker.image = original
self.picker.savedImage = true
} else if let metadata = info[UIImagePickerController.InfoKey.mediaMetadata] as? NSDictionary {
print(metadata)
}
self.picker.isPresented.wrappedValue.dismiss()
}
}
I put breakpoints within the last method above and nothing is triggering. Not sure why.
Here is how I implemented the ImagePickerView to present itself
@State private var sourceType: UIImagePickerController.SourceType?
@State private var savedImage: Bool = false
@State private var savedVideo: Bool = false
@State private var isImagePickerDisplay = false
@State var video: AVAsset?
@State var image: UIImage?
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0){
Spacer()
Button(action: {
//Opens up camera app
self.sourceType = .camera
self.isImagePickerDisplay.toggle()
}, label: {
Image(systemName: "camera")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(Color("Color2"))
}).frame(width: 50, height: 50, alignment: .leading)
Button(action: {
//Opens up photo library
self.sourceType = .photoLibrary
self.isImagePickerDisplay.toggle()
}, label: {
Image(systemName: "photo.on.rectangle")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(Color("Color2"))
}).frame(width: 50, height: 50, alignment: .leading)
}
ZStack{
if let image = image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: width, height: width, alignment: .center)
} else if video != nil {
UploadPlayerView(upload: uploadViewModel,
frame: CGRect(x: 0, y: 0, width: width*3, height: (width*3)*9/16))
} else {
//grid().gridStyle(StaggeredGridStyle(.vertical, tracks: 3, spacing: 0))
}
}
.frame(width: width, height: width)
}
.sheet(isPresented: $isImagePickerDisplay, content: {
PickerView(savedImage: $savedImage, savedVideo: $savedVideo, video: $video, image: $image, sourceType: self.sourceType)
})
}
I am suppose to see my ZStack change views to an image or video depending on the user's selection. I am not getting any change in the video or image variable which made me believe that the Coordinator is not working as intended
You need to assign delegate unconditionally, but you assign it only if sourceType
is not nil.
Here is fixed part
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
if let type = self.sourceType {
imagePicker.sourceType = type
// probably this line also should be moved out of condition
imagePicker.mediaTypes = ["public.image", "public.movie"] // << ??
}
imagePicker.delegate = context.coordinator // << this one !!
return imagePicker
}