如何从ForEach列表中的项目中访问值

时间:2019-11-21 13:51:28

标签: xcode swiftui swiftui-list

如何从使用ForEach创建的列表中的特定项目访问值? 如您所见,我正在尝试类似的方法(以及许多其他选择):

Text(item [2] .onOff?“ On”:“ Off”)

我想检查第二个列表项的切换值(例如),并更新屏幕上的文字,说明该文字是打开还是关闭。

我知道这与@Binding有关,我正在搜索此类示例并尝试了一些尝试,但我无法使其正常工作。也许这是一个初学者的问题。如果有人可以帮助我,我将不胜感激。

我的ContentView:

struct ContentView: View {

    //  @Binding var onOff : Bool
    @State private var onOff = false
    @State private var test = false

    var body: some View {
        NavigationView {
            List {

                HStack {
                    Text("Is 2nd item on or off? ")
                    Text(onOff ? "On" : "Off")
//                  Text(item[2].onOff ? "On" : "Off")
                }

                ForEach((1...15), id: \.self) {item in
                    ListItemView()
                }

            }
            .navigationBarTitle(Text("List"))
        }
    }
}

和ListItemView:

import SwiftUI

struct ListItemView: View {

    @State private var onOff : Bool = false
    //  @Binding var onOff : Bool

    var body: some View {
        HStack {

            Text("99")
                .font(.title)

            Text("List item")

            Spacer()

            Toggle(isOn: self.$onOff) {
                Text("Label")
            }
            .labelsHidden()
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我不知道您到底想实现什么,但是我为您提供了一个可行的示例:

struct ListItemView: View {

    @ObservedObject var model: ListItemModel

    var body: some View {
        HStack {

            Text("99")
                .font(.title)

            Text("List item")

            Spacer()

            Toggle(isOn: self.$model.switchedOnOff) {
                Text("Label")
            }
            .labelsHidden()
        }
    }
}

class ListItemModel: ObservableObject {
    @Published var switchedOnOff: Bool = false
}

struct ContentView: View {

    @State private var onOff = false
    @State private var test = false

    @State private var list = [
        (id: 0, model: ListItemModel()),
        (id: 1, model: ListItemModel()),
        (id: 2, model: ListItemModel()),
        (id: 3, model: ListItemModel()),
        (id: 4, model: ListItemModel())
    ]

    var body: some View {
                NavigationView {
                    List {

                        HStack {
                            Text("Is 2nd item on or off? ")
                            Text(onOff ? "On" : "Off")
        //                  Text(item[2].onOff ? "On" : "Off")
                        }

                        ForEach(self.list, id: \.id) {item in
                            ListItemView(model: item.model)
                        }

                    }
                    .navigationBarTitle(Text("List"))
                }.onReceive(self.list[1].model.$switchedOnOff, perform: { switchedOnOff_second_item in
                    self.onOff = switchedOnOff_second_item
                })
    }
}

@Published基本上会创建一个Publisher,UI可以根据onReceive()来监听它。

尝试一下,您将弄清楚这些事情是做什么的!

祝你好运:)

答案 1 :(得分:1)

import SwiftUI

struct ContentView: View {

        @State private var onOffList = Array(repeating: true, count: 15)

        var body: some View {
            NavigationView {
                List {

                    HStack {
                        Text("Is 2nd item on or off? ")
                        Text(onOffList[1] ? "On" : "Off")
                    }
                    ForEach((onOffList.indices), id: \.self) {idx in
                        ListItemView(onOff: self.$onOffList[idx])
                    }
                }
                .navigationBarTitle(Text("List"))
            }
        }
    }

    struct ListItemView: View {

        @Binding var onOff : Bool

        var body: some View {
            HStack {
                Text("99")
                    .font(.title)
                Text("List item")
                Spacer()
                Toggle(isOn: $onOff) {
                    Text("Label")
                }
                .labelsHidden()
            }
        }
    }

答案 2 :(得分:0)

我了解您正在指示我使用ObservableObject。可能这是最终产品的最佳选择。但是我仍然在考虑@Binding,因为我只需要在两个视图之间更好地传递值。也许我还是不懂绑定,但是我来到了这个解决方案。

struct ContentView: View {

    //  @Binding var onOff : Bool
    @State private var onOff = false
//  @State private var test = false

    var body: some View {
        NavigationView {
            List {

                HStack {
                    Text("Is 2nd item on or off? ")
                    Text(onOff ? "On" : "Off")
//                  Text(self.item[2].$onOff ? "On" : "Off")
//                  Text(item[2].onOff ? "On" : "Off")
                }

                ForEach((1...15), id: \.self) {item in
                    ListItemView(onOff: self.$onOff)
                }

            }
            .navigationBarTitle(Text("List"))
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

和ListItemView:

import SwiftUI

struct ListItemView: View {

//  @State private var onOff : Bool = false
    @Binding var onOff : Bool

    var body: some View {
        HStack {

            Text("99")
                .font(.title)

            Text("List item")

            Spacer()

            Toggle(isOn: self.$onOff) {
                Text("Label")
            }
            .labelsHidden()
        }
    }
}

现在发生的事情是我点击切换后正在更新文本。但是我有两个问题:

  • 点击1切换将其全部更改。我认为是因为这一行:

    ListItemView(onOff:self。$ onOff)

  • 我仍然无法访问仅一行的值。根据我的理解,ForEach((1 ... 15),id:.self)使每一行都有自己的id,但是我不知道以后如何访问它。