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

SwiftUI中点击List行内按钮如何将选中对象传递到第二个视图

问题根因

你当前写法的核心问题有两个:

  1. 在Button的点击闭包里创建SecondView实例完全无效,这个临时实例没有被加入到SwiftUI的视图渲染层级中,不会被展示
  2. 全局的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:54:04