Hello everyone! I'm using PHPickerViewController
in a UIViewControllerRepresentable
for a SwiftUI app, but I noticed when I present it using sheet(isPresented:content:)
, I can't seem to get interactive dismissal to work on it. I tried to add the interactiveDismissDisabled(false)
modifier to the view, with no luck either. The only way to dismiss is either select a photo or to press cancel in the navigation bar.
When I display a PHPickerViewController
in UIKit using UIViewController.present(_:animated:completion:)
, it seems like interactive dismissal works out of the box. I was just wondering if I might be setting something up wrong?
Here's how my code looks like:
struct PhotoPicker: UIViewControllerRepresentable {
@Binding var isPresented: Bool
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration()
configuration.filter = .images
configuration.selectionLimit = 1
let controller = PHPickerViewController(configuration: configuration)
controller.delegate = context.coordinator
return controller
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { }
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: PHPickerViewControllerDelegate {
private let parent: PhotoPicker
init(_ parent: PhotoPicker) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
guard
let provider = results.first?.itemProvider,
provider.canLoadObject(ofClass: UIImage.self)
else {
complete()
return
}
provider.loadObject(ofClass: UIImage.self) { [weak self] itemReading, error in
if let image = itemReading as? UIImage {
print(image)
}
self?.complete()
}
}
private func complete() {
DispatchQueue.main.async { [weak self] in
self?.parent.isPresented = false
}
}
}
}
And then I display it in my view:
struct InstructionsView: View {
@State var isDisplayingPhotoPicker = false
var body: some View {
VStack {
Button {
// display photo picker on tap
isDisplayingPhotoPicker = true
} label: {
Text("Pick photo")
}
}
.sheet(isPresented: $isDisplayingPhotoPicker) {
print("selected photo")
} content: {
PhotoPicker(isPresented: $isDisplayingPhotoPicker)
}
}
}
Would appreciate anyone's input or insights on this, thanks!