如何在Swiftui中更改数组项

时间:2019-10-08 13:32:22

标签: ios swiftui

如何在Swift中更改List的项目? (结构项)

@State var people: [Person] = [
        .init(firstName: "Steve",
              lastName: "Jobs", image: #imageLiteral(resourceName: "jobs"), jobTitle: "Founder of Apple"),
        .init(firstName: "Tim", lastName: "Cook", image: #imageLiteral(resourceName: "cook"), jobTitle: "Apple CEO"),
        .init(firstName: "Jony", lastName: "Ive", image: #imageLiteral(resourceName: "ive"), jobTitle: "Head of Design")
    ]

我想将此数组的项目传递给另一个视图,并且该视图可以修改项目(类似类的函数)

我尝试更多类似的方式:

@State Person struct

可观察对象(不起作用) 直通(无效)

this image depict my issue

2 个答案:

答案 0 :(得分:0)

您必须提供Binding。 例如:

struct MySecondView: View {
    @Binding var people: [People]    

    var body: some View { ... }

    func modifyArray() { /* Do whatever you need here */ }
}

并在其他视图中将其初始化时将其传递到该视图,例如:

MySecondView(people: self.$people)    

答案 1 :(得分:0)

ObservableObject如果正确使用应该可以正常工作,SwiftUI的核心概念是唯一的事实来源。这就是Binding进入的地方,但是,如果您遍历列表,则会得到键入Person的值,而不是所需的Binding<Person>。您可以在迭代过程中使用索引,并将其传递到TextForm,以便它可以获取原始数组。

为了使代码更具可读性,我建议使用类似的视图模型

class PeopleViewModel: ObservableObject {

    @Published var people: [Person] = [
        .init(lastname: "Some", firstname: "Dude"),
        .init(lastname: "Other", firstname: "Dude"),
    ]
}

您必须使用@ObservedObject包装器在视图中进行观看。

struct PeopleList: View {

    @ObservedObject var viewModel = PeopleViewModel()

    var body: some View {
        NavigationView {
            List(viewModel.people.indices) { index in
                TextForm(viewModel: self.viewModel, index: index)
            }
        }
    }
}

TextForm的索引位于viewmodel实例的结尾。

struct TextForm: View {

    @ObservedObject var viewModel: PeopleViewModel
    var index: Int

    var body: some View {
        VStack {
            TextField("textField", text: self.$viewModel.people[index].firstname)
            Text(self.viewModel.people[index].firstname)
        }
    }
}

如果您真的想忽略视图模型,只需通过绑定槽索引即可。

            List(people.indices) { index in
                TextForm(item: self.$people[index])
            }
struct TextForm: View {

    @Binding var item: Person

    var body: some View {
        VStack {
            TextField("textField", text: self.$item.firstname)
            Text(self.item.firstname)
        }
    }
}