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

SwiftUI中通过@State触发导航无法跳转至目标页面问题求助

SwiftUI导航问题:点击"View All"无法跳转到目标页面

问题描述

我尝试从HomeView导航至PopularArtWorkFilterView,使用NavigationView与NavigationLink实现逻辑,但点击触发导航后,并未显示目标页面,仅出现"View All Popular art work"文本。

点击前效果:
点击前

点击后效果:
点击后

相关代码

HomeView.swift

struct HomeView: View {
    
    private let homeViewModel: HomeViewModel = HomeViewModel()
    
    @State var isPopularArtWorkViewAllTextClicked: Bool = false
    
    var body: some View {
        
        NavigationView {
            ScrollView(.vertical, showsIndicators: false) {
                VStack {
                    HomeTopView()
                        .padding(.horizontal, 20)
                        .padding(.bottom, 20)
                    
                    // Click event occures.
                    // But not navigate to PopularArtWorkFilterView
                    if isPopularArtWorkViewAllTextClicked {
                        NavigationLink("View All Popular art work", destination: PopularArtWorkFilterView())
                    }
                    
                    PopularArtWorkListView(
                        popularArtWorkList: homeViewModel.getPopularArtWorks(),
                        isViewAllClicked: $isPopularArtWorkViewAllTextClicked
                    ).padding(.bottom, 40)
                    
                    TrendingArtistListView(trendingArtistList: homeViewModel.getTrendingArtists())
                        .padding(.bottom, 40)
                    
                    BidArtEventInfoView(bidArtEvent: homeViewModel.getBidArtEvents()[1])
                }
            }
            .background(Color("background"))
        }
    }
}

PopularArtWorkListView.swift

struct PopularArtWorkListView: View {
    
    let popularArtWorkList: [PopularArtWork]
    
    // Variable for tracking Click Listener
    @Binding var isViewAllClicked: Bool
    
    var body: some View {
        
        VStack(spacing: 20) {
            HeaderView(
                istClicked: $isViewAllClicked
            ).padding(.horizontal, 20)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 20) {
                    ForEach(popularArtWorkList, id: \.id) { popularArtWork in
                        PopularArtWorkItemView(popularArtWork: popularArtWork)
                    }
                }.padding(.horizontal, 20)
            }
        }
    }
}

private struct HeaderView: View {
    
    // Variable for tracking Click Listener
    @Binding var istClicked: Bool
    
    var body: some View {
        
        HStack {
            Text("Popular Artwork")
                .font(.custom(.Urbanist_Bold, size: 20))
            
            Spacer()
            
            Text("View All")
                .font(.custom(.Urbanist_Bold, size: 15))
                .foregroundColor(.gray.opacity(0.7))
                .onTapGesture {
                    // Toggle @Binding variable to track the click listener 
                    istClicked.toggle()
                }
            
        }
    }
}

问题原因

当前实现的核心错误在于:

  • NavigationLink需要在NavigationView的视图层级中初始渲染时就存在,才能具备导航能力。你通过条件判断isPopularArtWorkViewAllTextClicked为true时才渲染它,此时它只是普通文本,无法触发导航。
  • 使用onTapGesture切换绑定变量的逻辑,不符合NavigationLink的设计逻辑,无法触发导航行为。

解决方案

方案一:直接在HeaderView中使用NavigationLink(推荐)

将HeaderView中的"View All"文本直接包裹在NavigationLink中,无需额外状态变量,代码更简洁:

修改HeaderView:

private struct HeaderView: View {
    var body: some View {
        HStack {
            Text("Popular Artwork")
                .font(.custom(.Urbanist_Bold, size: 20))
            
            Spacer()
            
            NavigationLink(destination: PopularArtWorkFilterView()) {
                Text("View All")
                    .font(.custom(.Urbanist_Bold, size: 15))
                    .foregroundColor(.gray.opacity(0.7))
            }
        }
    }
}

同时简化其他代码:

  • 删除HomeView中的isPopularArtWorkViewAllTextClicked变量及条件渲染的NavigationLink
  • 删除PopularArtWorkListView中的@Binding var isViewAllClicked参数,并修改调用处

方案二:使用isActive绑定控制导航

如果需要通过状态变量控制导航行为,可使用NavigationLink的isActive参数:

修改HomeView:

struct HomeView: View {
    private let homeViewModel: HomeViewModel = HomeViewModel()
    @State var isNavigateToPopularFilter: Bool = false
    
    var body: some View {
        NavigationView {
            ScrollView(.vertical, showsIndicators: false) {
                VStack {
                    HomeTopView()
                        .padding(.horizontal, 20)
                        .padding(.bottom, 20)
                    
                    // 隐藏的NavigationLink,通过isActive控制导航
                    NavigationLink("", destination: PopularArtWorkFilterView(), isActive: $isNavigateToPopularFilter)
                        .hidden()
                    
                    PopularArtWorkListView(
                        popularArtWorkList: homeViewModel.getPopularArtWorks(),
                        isViewAllClicked: $isNavigateToPopularFilter
                    ).padding(.bottom, 40)
                    
                    TrendingArtistListView(trendingArtistList: homeViewModel.getTrendingArtists())
                        .padding(.bottom, 40)
                    
                    BidArtEventInfoView(bidArtEvent: homeViewModel.getBidArtEvents()[1])
                }
            }
            .background(Color("background"))
        }
    }
}

修改HeaderView的点击逻辑(无需toggle,直接设置为true):

private struct HeaderView: View {
    @Binding var istClicked: Bool
    
    var body: some View {
        HStack {
            Text("Popular Artwork")
                .font(.custom(.Urbanist_Bold, size: 20))
            
            Spacer()
            
            Text("View All")
                .font(.custom(.Urbanist_Bold, size: 15))
                .foregroundColor(.gray.opacity(0.7))
                .onTapGesture {
                    istClicked = true
                }
        }
    }
}

内容的提问来源于stack exchange,提问作者Aminul Haque Aome

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:40:24