SwiftUI ForEach内部sheet未按id循环,点击按钮获取id错误问题
问题原因
- 你将
.sheet(isPresented:)修饰符放在了ForEach循环的每个子项内部,所有按钮共用同一个isSheetPresented状态变量。当状态触发弹窗时,SwiftUI在初始化阶段就已经固定了弹窗关联的item内容,所以会出现多个按钮触发同一个第一个item弹窗的问题。 LazyVGrid是懒加载容器,子项会随滚动复用,绑定在子项内部的sheet也会被复用,进一步导致选中的id和实际弹出内容不匹配的错乱问题。
修复方案
使用SwiftUI提供的sheet(item:)重载方法替代isPresented版本,直接绑定选中的item模型,同时将sheet修饰符移到循环外层,避免复用导致的绑定错乱。
修改后代码
struct PricesList: View { @ObservedObject var viewModel = ViewModel() // 替换原来的布尔状态,改为绑定选中的item,注意把YourItemType换成你自己定义的Item模型的实际类型 @State var selectedItem: YourItemType? var body: some View{ NavigationView{ ScrollView { LazyVGrid(columns: gridLayout, spacing: 15, content: { ForEach(viewModel.items, id: \.id) { item in VStack(alignment: .leading, spacing: 5){ Button(action: { // 点击时把当前item赋值给选中状态 self.selectedItem = item }, label: { Image(item.imageUrl) .resizable() .scaledToFit() .padding(10) }) }//:VSTACK .scaledToFit() .padding() .background(Color.white.cornerRadius(12)) .background(RoundedRectangle(cornerRadius: 12).stroke(Color.gray, lineWidth: 1)) }//: LOOP FOR EACH }).padding(5) .onAppear(perform: { viewModel.loadData() viewModel.postData() }) } // sheet移到外层,使用item绑定的重载方法 .sheet(item: $selectedItem) { item in WebView(url: item.link) } .navigationBarHidden(true) }//: NAVIGATION VIEW } //: BODY }
内容的提问来源于stack exchange,提问作者Rafaela Santos
相关产品推荐
相关产品推荐

