似乎如果您使用UIViewControllerRepresentable
在您的SwiftUI应用中实现视图控制器,那么当您通过sheet
展示它时,就无法滑动以将其关闭。您需要做些什么来支持滑动以关闭吗?
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>) { }
}
答案 0 :(得分:1)
可能的解决方案是添加类似 handle 的东西来拖动(没有样式 - 简化演示),
.sheet(isPresented: $showingPicker, content: {
VStack {
RoundedRectangle(cornerRadius: 8).fill(Color.gray)
.frame(width: 60, height: 8)
.padding(.top, 8)
PHPicker()
}
})
替代方案:解决方案是完全通过 UIKit 进行展示,只需在可表示的内部传递激活绑定即可。
这是一个可能的方法的演示。使用 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 !!
}
}
}