ios SwiftUI,从子视图中消除模态/页面

euoag5mw  于 2022-11-19  发布在  iOS
关注(0)|答案(3)|浏览(194)

我是Swift/SwiftUI新手,想知道如何从嵌套子视图中消除模态/页面。
首先,我从Flutter,UIHostingController,然后SwiftUI页面调用。(当前显示为模态...)
导航至SwiftUI后,我无法使用子视图中的@环境数据。
有什么方法可以让这个工作吗?提前感谢。

应用程序委派.swift

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = self.window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel.init(name: "com.example.show", binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler({
            (call, result) -> Void in
            if call.method == "sample" {
                let vc = UIHostingController(rootView: ContentView())
                vc.modalPresentationStyle = .fullScreen
                controller.present(vc, animated: true,completion: nil)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

内容视图.swift

struct ContentView: View{
    @Environment(\.presentationMode) var presentation: Binding<PresentationMode>
    private var childView: ChildView()

    var body: some View{
        NavigationView{
            ZStack{
                childView
                Button(action: {
// This works ************************
                    self.presentation.wrappedValue.dismiss()
                }, label: {
                    Text("close")
                })
            }
        }
    }
}

子视图.swift

struct ChildView: View{
    @Environment(\.presentationMode) var presentation: Binding<PresentationMode>

    var body: some View{
        Button(action: {
// This won't do anything *********************************
            self.presentation.wrappedValue.dismiss()
// nor this↓ **********************************************
            if #available(iOS 15.0, *) {
               @Environment(\.dismiss) var dismiss;
                dismiss()
                dismiss.callAsFunction()
            }
            }, label: {
                Text("close")
            })
    }
}
7y4bm7vi

7y4bm7vi1#

我发现是ContentView.swift中的NavigationView导致了这个问题。
正在删除NavigationView,我可能会从子视图中关闭模式页面...
但这不是我的本意:(...

var body: some View{
//        NavigationView{    <--------
            ZStack{
                childView
                Button(action: {
                    self.presentation.wrappedValue.dismiss()
                }, label: {
                    Text("close")
                })
            }
//        }
    }
vddsk6oq

vddsk6oq2#

因为你有另一个NavigationView是你的ContentView,所以ChildView里面的@Environment(\.presentation)是一个子视图,而不是父视图。基本上,这两个视图来自完全不同的Navigation堆栈。
为了使NavigationView仍然保持在父ContentView中,您需要从ChildView的构造函数而不是从environment传递presentation值:

内容视图.swift

struct ContentView: View{
    @Environment(\.presentationMode) var presentation: Binding<PresentationMode>

    var body: some View{
        NavigationView{
            ZStack{
                ChildView(parentPresentation: presentation)
                Button(action: {
                    self.presentation.wrappedValue.dismiss()
                }, label: {
                    Text("close")
                })
            }
        }
    }
}

在子视图中,使用normal属性代替@Environment

子视图.swift

struct ChildView: View{
    let parentPresentation: Binding<PresentationMode>

    var body: some View{
        Button(action: {
            self.parentPresentation.wrappedValue.dismiss()
            if #available(iOS 15.0, *) {
                @Environment(\.dismiss) var dismiss;
                dismiss()
                dismiss.callAsFunction()
            }
        }, label: {
            Text("Close")
        })
    }
}
tjjdgumg

tjjdgumg3#

对于iOS 15.0及更高版本,我们可以使用新的环境值dismiss,为了使其与子视图一起工作,我们还应该将其从父视图传递到子视图:

内容视图.swift

struct ContentView: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationView {
            ZStack {
                ChildView(parentDismiss: dismiss)
                Button {
                    dismiss()
                } label: {
                    Text("close")
                }
            }
        }
    }
}

子视图.swift

struct ChildView: View {
    let parentDismiss: DismissAction

    var body: some View {
        Button {
            parentDismiss()
        } label: {
            Text("Close")
        }
    }
}

相关问题