如何使用 SwiftUI 在 iPad 上控制模态表的首选呈现大小?我很惊讶在谷歌上找到答案是多么困难。
此外,了解模态是否通过向下拖动(取消)或实际执行自定义积极操作来解除模式的最佳方法是什么?
最佳答案
这是我在 SwiftUI 中在 iPad 上显示表单的解决方案:
struct MyView: View {
@State var show = false
var body: some View {
Button("Open Sheet") { self.show = true }
.formSheet(isPresented: $show) {
Text("Form Sheet Content")
}
}
}
由此 UIViewControllerRepresentable 启用class FormSheetWrapper<Content: View>: UIViewController, UIPopoverPresentationControllerDelegate {
var content: () -> Content
var onDismiss: (() -> Void)?
private var hostVC: UIHostingController<Content>?
required init?(coder: NSCoder) { fatalError("") }
init(content: @escaping () -> Content) {
self.content = content
super.init(nibName: nil, bundle: nil)
}
func show() {
guard hostVC == nil else { return }
let vc = UIHostingController(rootView: content())
vc.view.sizeToFit()
vc.preferredContentSize = vc.view.bounds.size
vc.modalPresentationStyle = .formSheet
vc.presentationController?.delegate = self
hostVC = vc
self.present(vc, animated: true, completion: nil)
}
func hide() {
guard let vc = self.hostVC, !vc.isBeingDismissed else { return }
dismiss(animated: true, completion: nil)
hostVC = nil
}
func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
hostVC = nil
self.onDismiss?()
}
}
struct FormSheet<Content: View> : UIViewControllerRepresentable {
@Binding var show: Bool
let content: () -> Content
func makeUIViewController(context: UIViewControllerRepresentableContext<FormSheet<Content>>) -> FormSheetWrapper<Content> {
let vc = FormSheetWrapper(content: content)
vc.onDismiss = { self.show = false }
return vc
}
func updateUIViewController(_ uiViewController: FormSheetWrapper<Content>,
context: UIViewControllerRepresentableContext<FormSheet<Content>>) {
if show {
uiViewController.show()
}
else {
uiViewController.hide()
}
}
}
extension View {
public func formSheet<Content: View>(isPresented: Binding<Bool>,
@ViewBuilder content: @escaping () -> Content) -> some View {
self.background(FormSheet(show: isPresented,
content: content))
}
}
您应该可以修改 func show()
中的代码根据 UIKit 规范,以获得您喜欢的大小(如果需要,您甚至可以从 SwiftUI 端注入(inject)参数)。这就是我如何让表单在 iPad 上作为 .sheet
工作对我的用例来说太大了
关于在 iPad 上具有自定义大小的 SwiftUI sheet() 模态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60967872/