SwiftUI中点击List行内按钮如何将选中对象传递到第二个视图
问题根因
你当前写法的核心问题有两个:
- 在
Button的点击闭包里创建SecondView实例完全无效,这个临时实例没有被加入到SwiftUI的视图渲染层级中,不会被展示 - 全局的
sheet闭包默认无法拿到列表循环内的单个fruit对象,需要额外存储选中的水果对象
最优解决方案(推荐)
因为你的Fruit已经实现了Identifiable协议,可以直接使用sheet(item:)重载,无需单独维护弹出状态的布尔值,系统会自动在选中对象不为空时弹出sheet,为空时自动关闭:
struct ContentView: View { // 存储当前选中的水果,为nil时不弹出sheet @State private var selectedFruit: Fruit? var fruits = [Fruit(name: "Apple"), Fruit(name: "Orange")] var body: some View { List{ ForEach(fruits){ fruit in HStack{ Text(fruit.name) Button("Tap Me"){ // 点击时赋值选中的水果,触发sheet弹出 selectedFruit = fruit } .frame(width:150, height: 35) .background(Color.blue) .buttonStyle(BlueButton()) } } } // 直接绑定选中的水果对象,系统自动管理弹出状态 .sheet(item: $selectedFruit) { fruit in SecondView(selectedFruit: fruit) } } }
备选方案(沿用布尔状态的写法)
如果你一定要保留单独的弹出布尔状态控制,可以同时存储选中的水果对象:
struct ContentView: View { @State private var secondViewIsPresented = false @State private var selectedFruit: Fruit? var fruits = [Fruit(name: "Apple"), Fruit(name: "Orange")] var body: some View { List{ ForEach(fruits){ fruit in HStack{ Text(fruit.name) Button("Tap Me"){ selectedFruit = fruit secondViewIsPresented.toggle() } .frame(width:150, height: 35) .background(Color.blue) .buttonStyle(BlueButton()) } } } .sheet(isPresented: $secondViewIsPresented){ // 确保选中对象不为空时再传值 if let fruit = selectedFruit { SecondView(selectedFruit: fruit) } } } }
两种方案都可以正常在SecondView中展示选中的水果名称,完全不需要用到NavigationLink,不会和行本身的点击事件冲突。
内容的提问来源于stack exchange,提问作者fs_tigre
相关产品推荐
相关产品推荐

