SwiftUI 视图检测模式关闭

问题描述 投票:0回答:1

我有一个 SwiftUI 视图,包裹在

UIHostingController
中,并在 iPad 上以
formSheet
的形式呈现。我有一个完成按钮可以关闭,并且有一个从父视图控制器传递的回调闭包,以便在按下此完成按钮时执行操作。问题发生在 iPad 上,用户可能在视图之外点击,视图被关闭,从而错过了回调。

解决此问题的一种方法是在 SwiftUI 视图的

onDismiss
中触发回调闭包。虽然它有效,但我不确定它是否是正确的地方以及是否足够可靠。文档只说当“视图从屏幕上消失”时调用
onDismiss
。但是,如果我们在导航层次结构中将一个视图推到该视图的顶部,
onDismiss
仍然会被调用吗?

ios swift swiftui uikit uihostingcontroller
1个回答
0
投票

根据你的描述,我假设你有一个像这样的 SwiftUI 视图:

struct SomeView: View {
    let callback: () -> Void
    
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationStack {
            Text("Foo")
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button("Done") {
                            callback()
                            dismiss()
                        }
                    }
                }
        }
    }
}

在呈现托管控制器时,您可以设置其

presentationController
的委托并实现委托方法
presentationControllerDidDismiss
。例如:

@objc func somethingIsClicked() {
    let host = UIHostingController(rootView: SomeView(callback: callback))
    host.modalPresentationStyle = .formSheet
    host.presentationController?.delegate = self
    present(host, animated: true)
}

func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
    callback()
}

func callback() {
    print("Dismissed!")
}

presentationControllerDidDismiss
将在工作表完全关闭时调用,而不是当用户“开始”关闭它时(可以使用
presentationControllerWillDismiss
检测到),因为此时用户可以改变主意并停止关闭.

正如其文档所述,当以编程方式关闭工作表时,不会调用

presentationControllerDidDismiss
,因此您仍然需要将回调传递给 SwiftUI 视图。


另请注意,您可以设置:

host.isModalInPresentation = true

强制用户使用完成按钮关闭工作表。

© www.soinside.com 2019 - 2024. All rights reserved.