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

macOS Swift开发:NavigationLink使用问题及视图跳转方案咨询

macOS SwiftUI 视图跳转问题解答

你的 NavigationLink 呈灰色无法点击,核心问题是它必须放置在 NavigationView 的层级内部才能正常激活。当前代码里没有将 Sign In 视图包裹在 NavigationView 中,导致链接处于禁用状态。

修改 Sign In 视图,把内容包裹进 NavigationView:

struct SignInView: View {
    var body: some View {
        NavigationView { // 新增这层导航容器
            VStack {
                // 原有登录界面元素(比如账号密码输入框、登录按钮等)
                
                HStack{
                    Text("Don't have an account yet?")
                        .foregroundColor(.gray)
                }
                .padding(.top, 10)
                
                NavigationLink("Create Account", destination: SignUpView())
            }
        }
    }
}

修改后 NavigationLink 就能正常点击跳转了。

2. 是否应该使用 NavigationLink?

如果你的登录、注册视图是在同一个窗口的导航栈内切换(类似 iOS 的页面栈逻辑),用 NavigationLink 是合理的。但在 macOS 场景下,登录/注册界面通常作为独立窗口或弹窗展示,这种情况下 NavigationLink 并非最佳选择,推荐用下面的替代方案。

方案一:Sheet 弹窗展示

将注册界面作为弹窗弹出,适合轻量的注册流程:

struct SignInView: View {
    @State private var showSignUpSheet = false // 控制弹窗显示状态
    
    var body: some View {
        VStack {
            // 原有登录元素
            
            HStack{
                Text("Don't have an account yet?")
                    .foregroundColor(.gray)
                Button("Create Account") {
                    showSignUpSheet.toggle()
                }
            }
            .padding(.top, 10)
        }
        .sheet(isPresented: $showSignUpSheet) {
            SignUpView()
        }
    }
}

方案二:创建独立窗口(macOS 专属)

如果需要完全独立的窗口展示注册界面,可通过 NSWindow 实现:
先添加一个窗口管理工具方法:

func openSignUpWindow() {
    let signUpView = SignUpView()
    let window = NSWindow(
        contentRect: NSRect(x: 0, y: 0, width: 600, height: 500),
        styleMask: [.titled, .closable, .miniaturizable],
        backing: .buffered, defer: false
    )
    window.center()
    window.contentView = NSHostingView(rootView: signUpView)
    window.makeKeyAndOrderFront(nil)
}

然后在 Sign In 视图的按钮中调用:

Button("Create Account") {
    openSignUpWindow()
}

额外优化建议

你的 SignUpView 中直接使用 NSScreen.main?.visibleFrame 并强制解包 !,可能会在窗口调整或多屏幕场景下引发崩溃,建议改用 GeometryReader 获取视图尺寸:

struct SignUpView: View {
    @EnvironmentObject var viewModel: AppViewModel
    @State var email = ""
    @State var password = ""
    @State var keepLogged = false
    @State var alert = false
    
    var body: some View {
        GeometryReader { geometry in
            HStack(spacing: 0) {
                // 原有注册界面内容
            }
            .frame(width: geometry.size.width / 1.8, height: geometry.size.height - 100)
        }
        .ignoresSafeArea()
        .preferredColorScheme(.light)
        .alert(isPresented: $alert) {
            Alert(title: Text("提示"), message: Text("注册成功"), dismissButton: .default(Text("确定")))
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:46:03