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

SwiftUI MVVM中Toolbar内NavigationLink无法跳转视图问题排查

问题分析

你遇到的问题根源有两点:

  1. 直接在ToolbarItem的闭包内创建NavigationLink和AddViewModel,每次视图刷新都会重新执行这段代码,导致AddViewModel重复初始化。
  2. Toolbar的布局环境特殊,直接放置的NavigationLink交互触发逻辑会失效,无法正确触发页面跳转。
解决方案

方案一:绑定状态控制(兼容iOS 13+)

把NavigationLink移到主视图层级(不影响布局的背景层),用按钮控制绑定状态来触发跳转:

struct YourCurrentView: View {
    @State private var isAddViewPresented = false
    let viewModel: YourMainViewModel

    var body: some View {
        // 你的主视图内容
        Text("Main View")
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button(action: {
                        isAddViewPresented = true
                    }) {
                        Text("")
                    }
                    .buttonStyle(AddButtonStyle())
                }
            }
            .background(
                NavigationLink(
                    "",
                    destination: {
                        let vm = viewModel.add()
                        Add(viewModel: vm)
                    },
                    isActive: $isAddViewPresented
                )
            )
    }
}

方案二:使用navigationDestination(iOS 16+ 推荐)

iOS 16+提供了更简洁的跳转控制方式,无需手动管理NavigationLink的位置:

struct YourCurrentView: View {
    @State private var shouldNavigateToAdd = false
    let viewModel: YourMainViewModel

    var body: some View {
        // 你的主视图内容
        Text("Main View")
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button(action: {
                        shouldNavigateToAdd = true
                    }) {
                        Text("")
                    }
                    .buttonStyle(AddButtonStyle())
                }
            }
            .navigationDestination(isPresented: $shouldNavigateToAdd) {
                let vm = viewModel.add()
                Add(viewModel: vm)
            }
    }
}

额外注意

避免在ToolbarItem的闭包内创建需要保持状态的对象(比如ViewModel),这个闭包会因视图刷新被频繁调用,导致重复初始化。应该把ViewModel的创建放在跳转触发的时机(比如按钮的action或navigationDestination的闭包内),这样只会在跳转执行时初始化一次。

内容的提问来源于stack exchange,提问作者J. Holliday

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 11:52:11