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

SwiftUI点击加入购物车后View自动pop回产品分类页问题排查

问题原因

你遇到的自动pop导航栈、控制台输出Unable to present. Please file a bug.报错,核心是ProductsView的sheet布局错误导致SwiftUI导航状态混乱:

  • 你把sheet修饰符挂载到了ForEach循环的每一个商品单元格上,所有单元格共用同一个@State var showDetailView布尔状态变量
  • 当你点击加入购物车时,会修改ProductViewModel里@Published修饰的selectedProducts数组,触发整个ProductsView重绘
  • 重绘时多个共用同一状态的sheet会让SwiftUI无法正确管理页面层级,直接触发导航栈回退,出现自动返回产品分类页的问题
修复方案
  1. 移除ForEach内部每个单元格绑定的sheet修饰符,删除无用的@State var showDetailView变量
  2. 在ProductsView的根视图上使用sheet(item:)方法绑定selectedProduct来唤起商品详情页,避免状态冲突
    修改后的ProductsView核心代码示例:
struct ProductsView : View {
    @EnvironmentObject var prodViewModel : ProductViewModel
    var columns = Array(repeating:GridItem(.flexible()) , count: 2)
    @AppStorage("user_id") var userId = ""
    @Binding var catID : String
    @State var store : Store
    @State private var showToast = false
    @State var showCartView : Bool = false

    var body: some View{
        ScrollView{
            LazyVGrid(columns: columns, spacing:30){
                let withIndex = prodViewModel.productArray.enumerated().map({ $0 })
                ForEach(withIndex, id: \.element.id){ index, product in
                    ProductGridView(prodViewModel: _prodViewModel, showToast: $showToast, product: product,store: store)
                        .onTapGesture {
                            prodViewModel.ClickedProduct(product: product)
                        }
                }
            }
            // 原有导航栏配置保持不变
            .padding(.leading, 15)
            .padding(.trailing, 15)
            .navigationBarItems(trailing:
                                    Button(action: {
                                        self.showCartView.toggle()
                                    }) {
                                        Image(systemName: "cart.fill").imageScale(.large).font(.title3)
                                    }
                .overlay(Badge(count: prodViewModel.getSelectedProduct().count))
            )
        }
        // 移到外层的sheet,用item绑定自动管理状态
        .sheet(item: $prodViewModel.selectedProduct) { product in
            ProductDetailsView(store: store, showDetailView: .constant(false))
            // 建议ProductDetailsView内部使用@Environment(\.dismiss)来关闭页面,不需要外部传Binding
        }
        // 原有toast、NavigationLink、onAppear配置保持不变
        .toast(isShowing: $showToast, msg: "Added to cart", img: "cart")
        .background(
            NavigationLink(
                destination: CartView(prodViewModel: _prodViewModel, store: store, selectedCatID: catID),
                isActive: $showCartView,
                label: {

                }
            )
        )
        .onAppear{
            prodViewModel.FetchProductByCategory(storeID: store.id ?? "", catID: catID)
        }
    }
}
  1. 可选优化:如果你的项目适配iOS 16+,可以将购物车的NavigationLink替换成navigationDestination修饰符,进一步降低导航状态冲突的概率。

内容的提问来源于stack exchange,提问作者Mac_Play

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:30:03