首页 > 解决方案 > 当点击一行中的按钮时,如何将列表中的选定对象传递给第二个视图

问题描述

在下面的代码中,我有一个每行都有一个按钮的列表。我想要的是能够在点击按钮时将所选内容Fruit从传递ContentViewSecondView。现在我可以呈现,SecondView但它是空白的,里面没有文字,换句话说,我看不到文字,Second View: [fruit name]。请注意,我不能使用 ,NavigationLink(destination:)因为当点击行时,我已经在使用它转到详细信息视图。

Second View当每行上的按钮被点击时,如何将选定的水果传递给?

水果对象

struct Fruit: Identifiable{
    var id = UUID()
    var name:String
}

内容视图:

struct ContentView: View {
    @State private var secondViewIsPresented = false
    
    var fruits = [Fruit(name: "Apple"), Fruit(name: "Orange")]
    
    var body: some View {
        List{
            ForEach(fruits){ fruit in
                HStack{
                    Text(fruit.name)
                    
                    Button("Tap Me"){
                        secondViewIsPresented.toggle()
                        SecondView(selectedFruit: fruit)
                    }
                    .frame(width:150, height: 35)
                    .background(Color.blue)
                    .buttonStyle(BlueButton())
                }
            }
        }
        .sheet(isPresented: $secondViewIsPresented){
            // Here I cannot access the selected fruit
        }
    }
}

// style to make the button in the row work properly
// I'm showing it just for reference.
struct BlueButton: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 2 : 1)
    }
}

第二视图

struct SecondView: View {
    var selectedFruit: Fruit
    
    var body: some View {
        Text("Second View: \(selectedFruit.name)")
    }
}

标签: swiftswiftui

解决方案


首先,SecondView在按钮的动作闭包内部声明无效。所有这一切都是创建一个SecondView,然后把它扔掉。

Button("Tap Me"){
    secondViewIsPresented.toggle()
    SecondView(selectedFruit: fruit) /// nope!
}

您想在一张纸中展示选定的水果,对吗?但正如您所说,问题是您无法从工作表中访问选定的水果。

这就是sheet(item:onDismiss:content:)进来的地方。当item不为零时,就会触发这种替代版本的工作表。然后,您可以访问其content闭包内的选定项目。

struct ContentView: View {
//    @State private var secondViewIsPresented = false // delete this line
    @State private var selectedFruit: Fruit? /// replace with this
    
    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 /// set the fruit
                    }
                    .frame(width:150, height: 35)
                    .background(Color.blue)
                    .buttonStyle(BlueButton())
                }
            }
        }
        .sheet(item: $selectedFruit) { fruit in /// access selected fruit inside content closure
            SecondView(selectedFruit: fruit)
        }
    }
}

结果:

工作表显示正确的项目

推荐阅读