It seems if you use UIViewControllerRepresentable
to implement a view controller in your SwiftUI app, when you present it via sheet
you cannot swipe to dismiss it. Is there something you need to do to support swipe to dismiss?
struct ContentView: View {
@State var showingPicker = false
var body: some View {
Text("Hello, world!")
.onAppear {
showingPicker = true
}
.sheet(isPresented: $showingPicker, content: {
PHPicker() //cannot swipe to dismiss
//Text("Test") //can swipe to dismiss
})
}
}
struct PHPicker: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<PHPicker>) -> PHPickerViewController {
let config = PHPickerConfiguration()
return PHPickerViewController(configuration: config)
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: UIViewControllerRepresentableContext<PHPicker>) { }
}
Possible solution is to add something like handle to drag (no styling - simplified for demo),
.sheet(isPresented: $showingPicker, content: {
VStack {
RoundedRectangle(cornerRadius: 8).fill(Color.gray)
.frame(width: 60, height: 8)
.padding(.top, 8)
PHPicker()
}
})
Alternate: the solution is to make presentation by UIKit completely and just pass activation binding inside representable.
Here is a demo of possible approach. Tested with Xcode 12.1 / iOS 14.1
struct PHPickerContentView: View {
@State var showingPicker = false
var body: some View {
Button("Picker") {
showingPicker = true
}
.background(PHPicker(isPresented: $showingPicker)) // << here !!
}
}
struct PHPicker: UIViewControllerRepresentable {
@Binding var isPresented: Bool
func makeUIViewController(context: Context) -> UIViewController {
UIViewController() // << picker presenter
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
// react on binding & show if not shown
if isPresented && uiViewController.presentedViewController == nil {
let config = PHPickerConfiguration()
let picker = PHPickerViewController(configuration: config)
picker.delegate = context.coordinator
uiViewController.present(picker, animated: true)
picker.presentationController?.delegate = context.coordinator
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, PHPickerViewControllerDelegate, UIAdaptivePresentationControllerDelegate {
let owner: PHPicker
init(_ owner: PHPicker) {
self.owner = owner
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// picked image handling code here
picker.presentingViewController?.dismiss(animated: true)
owner.isPresented = false // << reset on action !!
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
owner.isPresented = false // << reset on swipe !!
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.