如何在SwiftUI中将对象传递给新视图 Person列表传递至PersonList视图实现问题
不需要把Person从struct改成class,你当前的写法存在几个属性包装器和传值的基础错误,按下面的步骤修改即可实现需求,完全符合Swift风格:
核心错误点说明
@StateObject只能用于遵循ObservableObject协议的类实例,数组是值类型,直接用@State包装即可,你当前用@StateObject修饰[Person]属于属性包装器误用,会直接编译报错- 第二个姓的TextField绑定变量错误,两个输入框都绑定了
$firstName,会导致输入的姓直接覆盖名 Person结构体没有遵循Identifiable协议,直接在List中遍历会报错,需要补充协议实现NavigationLink跳转时没有把人员数组传递给PersonList视图,导致第二个视图拿不到列表数据PersonList的@Binding属性不能设置默认值,预览时需要传入常量绑定用于展示
修改后的各文件代码
Person.swift
import Foundation // 遵循Identifiable协议,方便List直接遍历 struct Person: Identifiable { let id = UUID() // 自动生成唯一标识 var firstName: String var lastName: String }
ContentView.swift
struct ContentView: View { @State private var firstName: String = "" @State private var lastName: String = "" // 数组是值类型,用@State即可 @State private var listOfPersons: [Person] = [] var body: some View { NavigationView { ZStack (alignment: .top){ Color(.orange).opacity(0.2).edgesIgnoringSafeArea(.all) VStack { Text("Hello stranger") .font(.title) TextField("Fist name:", text: $firstName) .padding() // 修正绑定为lastName TextField("Last name:", text: $lastName) .padding() HStack(spacing: 40) { Button("Add to list") { listOfPersons.append(Person(firstName: firstName, lastName: lastName)) // 加完清空输入框,可选功能 firstName = "" lastName = "" } .padding() // 跳转时传递数组 NavigationLink(destination: PersonList(listOfPersons: listOfPersons)) { Text("Show list") } } } .padding() } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
PersonList.swift
import SwiftUI struct PersonList: View { // 仅展示不需要修改的话,直接用普通常量接收即可,不需要@Binding let listOfPersons: [Person] var body: some View { ZStack { Color(.orange).opacity(0.2).edgesIgnoringSafeArea(.all) List(listOfPersons) { person in PersonRow(person: person) } } .navigationTitle("人员列表") } } struct PersonList_Previews: PreviewProvider { static var previews: some View { // 预览时传入测试数据 PersonList(listOfPersons: [ Person(firstName: "张", lastName: "三"), Person(firstName: "李", lastName: "四") ]) } }
PersonRow.swift
无需修改,原有代码可直接使用。
补充说明:如果你后续需要在PersonList页面修改列表内容,再把属性改成
@Binding var listOfPersons: [Person],跳转时传值改为PersonList(listOfPersons: $listOfPersons)即可。
内容的提问来源于stack exchange,提问作者Marta
相关产品推荐
相关产品推荐

