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

SwiftUI点击商品跳转详情页时隐藏marketplaceFilterBar的方法

问题原因

之前用绑定布尔值控制筛选栏显隐失效,核心是三个问题:

  1. 详情页显隐状态零散存在局部视图里,没有统一放到全局共享的SharedDataModel中,商城父视图拿不到实时的详情页打开状态
  2. 商城页的枚举判断写错了,把定义好的.shirts/.trousers枚举值写成了.raise/.save,分支逻辑根本不会触发
  3. 代码里混进了和商城模块无关的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:24:30