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

Item详情视图异常:未点击添加按钮无法展示选中项详情

问题分析

你的问题根源在于使用isPresented绑定sheet的方式存在视图缓存问题:SwiftUI会缓存通过isPresented触发的sheet视图,初始状态下createItem为true,第一次点击现有Item时,即便你修改了createItem和selectedItem,sheet内容仍会沿用第一次初始化时捕获的createItem=true状态,导致显示新Item。另外,代码中强制解包selectedItem!还存在崩溃风险。

解决方案

改用sheet(item:)API替代isPresented,该API会根据绑定的可选对象自动管理sheet的展示/隐藏,且对象变化时会重新初始化sheet内容,彻底解决缓存问题。同时移除多余的createItem状态变量,简化逻辑:

struct ItemListView: View {
    @Query private var allItems: [Item]
    @State private var selectedItem: Item? // 统一管理新增、编辑的Item数据源

    var body: some View {
        VStack {
            List {
                ForEach(allItems) { item in
                    VStack(alignment: .leading) {
                        Text(item.name)
                            .onTapGesture {
                                selectedItem = item // 点击现有Item,赋值选中对象
                            }
                    }
                }
            }
            
            HStack {
                Button(action: {
                    selectedItem = Item() // 点击新增按钮,赋值新的Item实例
                }, label: {
                    HStack {
                        Image(systemName: "plus")
                        Text("Add item")
                    }
                })
                
                Spacer()
                
                Button(action: {
                    
                }, label: {
                    HStack {
                        Image(systemName: "pencil.tip.crop.circle")
                        Text("Edit items")
                    }
                })
            }.padding()
        }
        .navigationTitle("Items")
        // 通过sheet(item:)绑定selectedItem,自动处理展示逻辑
        .sheet(item: $selectedItem) { item in
            ItemDetailsView(item: item)
        }
    }
}
关键修改说明
  • 移除createItem和isPresented状态,用selectedItem统一管理新增、编辑的数据源
  • sheet(item:)会在selectedItem从nil变为非nil时展示sheet,从非nil变为nil时隐藏sheet
  • 每次selectedItem变化(选中现有Item或创建新Item),sheet都会重新初始化ItemDetailsView,确保展示正确内容
  • 消除了原代码中强制解包selectedItem!的崩溃风险

注意:确保Item结构体已遵循Identifiable协议(这也是你能在ForEach中直接使用Item的前提),若未遵循需补充:

struct Item: Identifiable {
    let id = UUID()
    // 你的其他属性,如name等
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:20:14