SwiftUI点击商品跳转详情页时隐藏marketplaceFilterBar的方法
问题原因
之前用绑定布尔值控制筛选栏显隐失效,核心是三个问题:
- 详情页显隐状态零散存在局部视图里,没有统一放到全局共享的
SharedDataModel中,商城父视图拿不到实时的详情页打开状态 - 商城页的枚举判断写错了,把定义好的
.shirts/.trousers枚举值写成了.raise/.save,分支逻辑根本不会触发 - 代码里混进了和商城模块无关的Charity、Business相关绑定参数,干扰了状态判断
修复步骤
- 补全全局共享数据模型
把裤子的详情状态也统一放到SharedDataModel里,所有视图都从环境对象读取这个全局状态,避免多视图状态不同步:
class SharedDataModel: ObservableObject { // 衬衫详情相关状态 @Published var detailShirt : Shirt? @Published var showDetailShirt : Bool = false // 新增裤子详情相关状态 @Published var detailTrouser: Trouser? @Published var showDetailTrouser: Bool = false @Published var fromSearchPage: Bool = false }
- 修正商城页逻辑
删掉和商城无关的Charity、Business绑定参数,修正枚举判断错误,直接读取全局状态控制筛选栏显隐:
struct Marketplace: View { @EnvironmentObject var sharedData: SharedDataModel @State private var selectedMarketplaceFilter: MarketplaceFilterViewModel = .shirts @Namespace var animation var body: some View { ZStack { ScrollView(.vertical, showsIndicators: false) { VStack(spacing: 10){ // 两个详情页都未打开时才显示筛选栏 if !sharedData.showDetailShirt && !sharedData.showDetailTrouser { marketplaceFilterBar } // 修正之前写错的枚举值 if selectedMarketplaceFilter == .shirts { MarketplaceShirtView() } if selectedMarketplaceFilter == .trousers { MarketplaceTrouserView() } } } // 浮层展示详情页 if sharedData.showDetailShirt { ShirtDetailView() .transition(.opacity) } if sharedData.showDetailTrouser { TrouserDetailView() .transition(.opacity) } } } var marketplaceFilterBar: some View { VStack { HStack(spacing: 15){ Image("Logo") .resizable() .aspectRatio(contentMode: .fill) .frame(width: 60.0, height: 60.0) .padding(.leading, 45) Spacer(minLength: 0) } .padding([.horizontal,.top]) HStack { ForEach(MarketplaceFilterViewModel.allCases, id: \.rawValue) { item in VStack { Text(item.title) .font(.headline) .fontWeight(selectedMarketplaceFilter == item ? .semibold: .regular) .foregroundColor(selectedMarketplaceFilter == item ? .black: .gray) if selectedMarketplaceFilter == item { Capsule() .foregroundColor(Color("LightBlue")) .frame(height: 3) .matchedGeometryEffect(id: "filter", in: animation) } else { Capsule() .foregroundColor(.clear) .frame(height: 3) } } .onTapGesture { withAnimation(.easeInOut) { self.selectedMarketplaceFilter = item } } } } .overlay(Divider().offset(x: 0, y: 16)) } } }
- 修正两个详情页逻辑
删掉局部传入的Binding参数,直接读写全局共享状态,保证状态变更能实时同步到商城页:
// 衬衫详情页 struct ShirtDetailView: View { @EnvironmentObject var sharedData: SharedDataModel @Namespace var animation: Namespace.ID private var shirtData: Shirt { sharedData.detailShirt! } var body: some View { ScrollView { VStack{ HStack { Button(action: { withAnimation(.easeOut){ sharedData.showDetailShirt = false } }) { Image(systemName: "arrow.backward.circle.fill") .foregroundColor(.gray) .frame(width: 40, height: 40) .background(Color.white,in: RoundedRectangle(cornerRadius: 10, style: .continuous)) .shadow(color: .black.opacity(0.1), radius: 5, x: 5, y: 5) } Text(shirtData.shirt_name) .font(.largeTitle) .fontWeight(.heavy) .foregroundColor(.black) } VStack(spacing: 10){ WebImage(url: URL(string: shirtData.shirt_image)) .resizable() .aspectRatio(contentMode: .fill) .edgesIgnoringSafeArea(.all) .cornerRadius(15) Text("Details") .opacity(0.7) .frame(maxWidth: .infinity,alignment: .leading) .padding(.bottom) HStack(spacing: 15) { Text(shirtData.shirt_details) .font(.system(size: 18)) .padding() } } } } } }
// 裤子详情页 struct TrouserDetailView: View { @EnvironmentObject var sharedData: SharedDataModel @Namespace var animation: Namespace.ID private var trouserData: Trouser { sharedData.detailTrouser! } var body: some View { ScrollView { VStack{ HStack { Button(action: { withAnimation(.easeOut){ sharedData.showDetailTrouser = false } }) { Image(systemName: "arrow.backward.circle.fill") .foregroundColor(.gray) .frame(width: 40, height: 40) .background(Color.white,in: RoundedRectangle(cornerRadius: 10, style: .continuous)) .shadow(color: .black.opacity(0.1), radius: 5, x: 5, y: 5) } Text(trouserData.trouser_name) .font(.largeTitle) .fontWeight(.heavy) .foregroundColor(.black) } VStack(spacing: 10){ WebImage(url: URL(string: trouserData.trouser_image)) .resizable() .aspectRatio(contentMode: .fill) .edgesIgnoringSafeArea(.all) .cornerRadius(15) Text("Details") .opacity(0.7) .frame(maxWidth: .infinity,alignment: .leading) .padding(.bottom) HStack(spacing: 15) { Text(trouserData.trouser_details) .font(.system(size: 18)) .padding() } } } } } }
- 修正商品卡片点击逻辑
点击商品时给全局状态赋值,触发详情页展示:
// 衬衫商品卡片点击事件 .onTapGesture { withAnimation(.easeInOut) { sharedData.detailShirt = shirt sharedData.showDetailShirt = true } } // 裤子商品卡片点击事件 .onTapGesture { withAnimation(.easeInOut) { sharedData.detailTrouser = trouser sharedData.showDetailTrouser = true } }
内容的提问来源于stack exchange,提问作者Mxyb
相关产品推荐
相关产品推荐

