如何在 SwiftUI 中预填表单

How to pre-fill Form in SwiftUI

我目前在 SwiftUIForms 一起工作。我正在实施 EditUser View,因此我正在尝试 使用之前的 Inputs

预填充 Form

I am passing a User Object which contains all the relevant Data and using the initializer to update all of the input states.

struct EditUserView: View {
    
    let user: User?
    @Binding var showEditUserView: Bool
    
    @State private var gender: User.Gender = .notSet
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    
    init(for user: User?, show: Binding<Bool>) {
        // First, update the Struct Properties with the given Values
        self.user = user
        self._showEditUserView = show
        
        // Second, if a User was given, update all Inputs with the given Values
        if let safeUser = user {
            gender = safeDoctor.gender
            firstName = safeDoctor.firstName
            lastName = safeDoctor.lastName
        }
    }

    // Some other Code

    Picker(selection: $gender, label: Text("Gender")) {
        ForEach(User.Gender.allCases, id: \.self) { gender in
            if gender != .notSet { Text(gender.string).tag(gender) }
        }
    }
    HStack {
        TextField("FirstName", text: $firstName)
        Divider()
        TextField("LastName", text: $lastName)
    }

When creating a new instance of EditUserView while providing a User (NOT nil), the input fields are not getting updated with the provided values.

谁能找出这不起作用的原因?

感谢您的帮助。

将设置 @State 变量的代码放在 EditUserView.onAppear() 修饰符中,而不是初始化程序中。应该这样做。

在函数式编程中,我们可以跟踪Struct的变化,所以使用Struct作为模型(User)是最好的方式。

然后你可以像下面这样使用。

struct ContentView: View {
    
    @State var user: User
    var body: some View {
        VStack {
            TextField("FirstName", text: $user.firstName)
            Divider()
            TextField("LastName", text: $user.lastName)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(user: User(firstName: "christophriepe", lastName: "last name"))
    }
}

struct User {
    var firstName: String
    var lastName: String
}

状态应该以不同的方式初始化 - 不是按值,而是 State

这是固定的变体:

struct EditUserView: View {
    
    let user: User?
    @Binding var showEditUserView: Bool
    
    @State private var gender: User.Gender    // here declare only
    @State private var firstName: String
    @State private var lastName: String
    
    init(for user: User?, show: Binding<Bool>) {
        // First, update the Struct Properties with the given Values
        self.user = user
        self._showEditUserView = show
        
        // Second, if a User was given, update all Inputs with the given Values
        self._gender = State(initialValue: user.gender ?? .notSet)
        self._firstName = State(initialValue: user.firstName ?? "")
        self._lastName = State(initialValue: user.lastName ?? "")
    }

    // ... other code