You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI实现按钮点击条件式导航:隐藏NavigationLink

SwiftUI 实现带条件的编程式导航

问题描述

我有一个SwiftUI Button,需要检查条件isSmiling:当该布尔值为true时,通过NavigationStack跳转到新视图;否则显示弹窗。目前我同时使用了NavigationLink和Button,但希望仅通过按钮在点击且isSmiling为true时编程式导航,且不显示NavigationLink,该如何实现?

原代码如下:

struct ControlView: View {
  @Binding var isSmiling: Bool
    
  @State private var showingAlert = false


  var body: some View {
    VStack {
        Spacer()
        NavigationStack {
            VStack(alignment: .leading) {
                Text("Please smile !!! Click button to continue").bold().font(.title3).padding(.bottom).background(.white)
                HStack(spacing: 12) {
                    
                    NavigationLink {
                        WelcomeView()
                    } label: {
                        ZStack {
                            RoundedRectangle(cornerRadius: 10)
                                .foregroundColor(.blue)
                            Text("Validate").font(.title3)
                                .foregroundColor(.white)
                        }
                    }.frame(width: 100, height: 50).padding(.top, 10)
                    
                    Button("Validate") {
                        print("isSmiling = \(isSmiling)")
                        if !isSmiling {
                            showingAlert = true
                        }
                        
                    }.buttonStyle(.borderedProminent)
                        .tint(.blue)
                        .controlSize(.large)
                        .alert(isPresented: $showingAlert) {
                            Alert(title: Text("Livliness detection failed"),
                                  message: Text("Please smile!"),
                                  dismissButton: .default(Text("Got it!")))
                        }
                }
            }
        }
    }
  }
}

解决方案

可以通过NavigationStack的路径绑定实现编程式导航,无需保留多余的NavigationLink,具体修改如下:

修改后的完整代码

struct ControlView: View {
    @Binding var isSmiling: Bool
    @State private var showingAlert = false
    // 定义导航路径,用于编程式控制跳转
    @State private var navigationPath = NavigationPath()

    var body: some View {
        VStack {
            Spacer()
            // 将navigationPath绑定到NavigationStack
            NavigationStack(path: $navigationPath) {
                VStack(alignment: .leading) {
                    Text("请微笑!点击按钮继续")
                        .bold()
                        .font(.title3)
                        .padding(.bottom)
                        .background(.white)
                    
                    Button("验证") {
                        print("isSmiling = \(isSmiling)")
                        if isSmiling {
                            // 满足条件时,往路径中添加目标视图实现跳转
                            navigationPath.append(WelcomeView())
                        } else {
                            // 不满足条件时显示弹窗
                            showingAlert = true
                        }
                    }
                    .buttonStyle(.borderedProminent)
                    .tint(.blue)
                    .controlSize(.large)
                    .alert(isPresented: $showingAlert) {
                        Alert(title: Text("活体检测失败"),
                              message: Text("请微笑!"),
                              dismissButton: .default(Text("知道了")))
                    }
                }
            }
        }
    }
}

// 假设WelcomeView的定义如下(如果已有可忽略)
struct WelcomeView: View {
    var body: some View {
        Text("欢迎页面")
            .font(.title)
    }
}

关键说明

  • 使用NavigationPath类型的@State变量navigationPath绑定到NavigationStack,通过修改这个路径数组来控制导航行为
  • 移除原有的NavigationLink,只保留一个按钮处理所有逻辑
  • 按钮点击时直接判断isSmiling:
    • 为true时,调用navigationPath.append(目标视图)完成编程式跳转
    • 为false时,触发弹窗显示

这种方式完全通过代码控制导航,不需要依赖NavigationLink的界面元素,符合需求。

内容的提问来源于stack exchange,提问作者etayluz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:25:01