swift 打开工作表并覆盖当前工作表,或在工作表内提供内部导航堆栈

ybzsozfc  于 2022-11-21  发布在  Swift
关注(0)|答案(1)|浏览(143)

所以我有一个按钮如下所示:

private var getStartedButton: some View {
    Button {
        showGetStartedSheet.toggle()
    } label: {
        Text("Get Started")
    }
    .sheet(isPresented: $showGetStartedSheet) {
        LoginUserSheetView()
            .presentationDetents([.fraction(0.70), .large])
    }
}

它打开LoginUserSheetView()视图,并在其中包含以下函数:

private var userCreateAccount: some View {
    VStack(alignment: .center) {
        Text("New MapGliders? User register")
            .sheet(isPresented: $showUserRegisterSheet) {
                RegisterUserSheetView()
                    .presentationDetents([.fraction(0.70), .large])
            }
    }
}

上面的代码,然后打开另一个工作表,其中显示以下代码:

private var appleButton: some View {
    Button {
        // Hello
    } label: {
        HStack(alignment: .firstTextBaseline) {
            Image(systemName: "applelogo")
            Text("Hello")
        }
    }
}

上述代码(已删除批次)生成以下输出:
https://im4.ezgif.com/tmp/ezgif-4-4ecfdb6d55.gif
正如您可以看到上面的视频,第二张图纸在旧图纸的顶部打开,我希望覆盖该图纸或在单张图纸上创建导航。
有人知道如何在RegisterUserSheetView()打开时关闭LoginUserSheetView()吗?或者如何在LoginUserSheetView()打开时覆盖工作表,甚至使用导航定位到RegisterUserSheetView()

dced5bon

dced5bon1#

第一个选项是使用sheet(item:)。但这会消除工作表,并使其以新值重新显示

struct DynamicOverlay: View {
    @State var selectedOverlay: OverlayViews? = nil
    var body: some View {
        VStack{
            Text("hello there")
            Button("first", action: {
                selectedOverlay = .first
            })
            
        }
        .sheet(item: $selectedOverlay){ passed in
            passed.view($selectedOverlay)
        }
    }
    enum OverlayViews: String, Identifiable{
        var id: String{
            rawValue
        }
        case first
        case second
        
        @ViewBuilder func view(_ selectedView: Binding<OverlayViews?>) -> some View{
            switch self{
            case .first:
                ZStack {
                    Color.blue
                        .opacity(0.5)
                    
                    Button {
                        selectedView.wrappedValue = .second
                    } label: {
                        Text("Next")
                    }
                }
            case .second:
                ZStack {
                    
                    Color.red
                        .opacity(0.5)
                    Button("home") {
                        selectedView.wrappedValue = nil
                    }
                }
                
            }
        }
    }
}

第二个选项没有动画行为,但需要一个小的“中间人”View

import SwiftUI

struct DynamicOverlay: View {
    @State var selectedOverlay: OverlayViews = .none
    @State var presentSheet: Bool = false
    var body: some View {
        VStack{
            Text("hello there")
            Button("first", action: {
                selectedOverlay = .first
                presentSheet = true
            })
            
        }
        .sheet(isPresented: $presentSheet){
            //Middle-main
            UpdatePlaceHolder(selectedOverlay: $selectedOverlay)
        }
    }
    enum OverlayViews{
        case first
        case second
        case none
        
        @ViewBuilder func view(_ selectedView: Binding<OverlayViews>) -> some View{
            switch self{
            case .first:
                ZStack {
                    Color.blue
                        .opacity(0.5)
                    
                    Button {
                        selectedView.wrappedValue = .second
                    } label: {
                        Text("Next")
                    }
                }
            case .second:
                ZStack {
                    
                    Color.red
                        .opacity(0.5)
                    Button("home") {
                        selectedView.wrappedValue = .none
                    }
                }
            case .none:
                EmptyView()
            }
        }
    }
    //Needed to reload/update the selected item on initial presentation
    struct UpdatePlaceHolder: View {
        @Binding var selectedOverlay: OverlayViews
        
        var body: some View{
            selectedOverlay.view($selectedOverlay)
            
        }
    }
    
}

您可以在此处SwiftUI阅读更多关于为什么需要中间视图的信息:了解使用常量与@Binding初始值设定项时的.sheet / .fullScreenCover生命周期

相关问题