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
相关产品推荐
相关产品推荐

