SwiftUI Sheet数组数据显示异常:点击项未正确展示
SwiftUI列表滑动触发Sheet始终显示最后一项,如何解决?
问题代码
import SwiftUI struct MyView: View { @State private var items = ["Apple", "Microsoft", "Google"] @State private var presentSheet = false var body: some View { NavigationStack { List { ForEach(items, id: \.self) { item in Text(item) .swipeActions(edge: .leading) { Button("Show", systemImage: "eye") { presentSheet.toggle() } .tint(Color.yellow) } .sheet(isPresented: $presentSheet) { Text(item) } } } .navigationTitle("MyView") } } }
问题说明
无论点击哪个列表项的滑动按钮触发Sheet,Sheet始终显示数组最后一项(如"Google"),而非触发操作的对应项。需求是让Sheet展示当前选中的列表项内容。
问题原因
- 所有列表项共用同一个布尔状态
presentSheet,无法区分触发源 - Sheet直接引用循环变量
item,SwiftUI循环结束后item会保留最后一次迭代的值,导致Sheet始终显示最后一项
解决方法
改用sheet(item:)API,绑定存储选中项的可选状态变量,让SwiftUI自动管理Sheet的显示与对应内容:
修改后的代码
import SwiftUI struct MyView: View { @State private var items = ["Apple", "Microsoft", "Google"] // 存储选中项的状态变量,nil表示不显示Sheet @State private var selectedItem: String? var body: some View { NavigationStack { List { ForEach(items, id: \.self) { item in Text(item) .swipeActions(edge: .leading) { Button("Show", systemImage: "eye") { // 点击时赋值当前项,触发Sheet显示 selectedItem = item } .tint(Color.yellow) } } } .navigationTitle("MyView") // 绑定选中项,非nil时自动显示Sheet .sheet(item: $selectedItem) { selectedItem in Text(selectedItem) } } } } // 为String扩展Identifiable协议,满足sheet(item:)的要求 extension String: Identifiable { public var id: String { self } }
代码说明
selectedItem状态变量专门存储当前选中的列表项,通过赋值操作触发Sheet显示.sheet(item:)API会根据selectedItem是否为nil自动控制Sheet的显示/隐藏,且Sheet内容直接绑定选中的具体项,不会受循环变量生命周期影响- 扩展
String实现Identifiable协议,是因为sheet(item:)要求绑定对象必须遵循该协议(如果使用自定义模型,直接让模型遵循协议即可)
内容的提问来源于stack exchange,提问作者Victor Vaknin Otte Hansen
相关产品推荐
相关产品推荐

