【问题标题】:How to pre-fill Form in SwiftUI如何在 SwiftUI 中预填表单
【发布时间】:2021-03-06 16:40:06
【问题描述】:

我目前在SwiftUI 中与Forms 合作。我正在实现一个 EditUser 视图,因此我正在尝试使用之前的输入预填充表单

我正在传递一个包含所有相关数据的 User Object,并使用 initializer 更新所有输入状态。

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)
    }

在提供用户(非零)的同时创建 EditUserView 的新实例时,输入字段不会使用提供的值进行更新。

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

感谢您的帮助。

【问题讨论】:

  • 您确定您确实在提供要更新的值吗?老实说,您最好将User 设为一个可以直接绑定到您的 TextField 的 ObservableObject。我怀疑您的解包失败,firstNamelastName 默认为空字符串,这是一个实际值,这就是您的文本字段显示的内容。你是否设置了断点来检查各个地方的值?
  • 为什么safeUser 变成safeDoctor

标签: ios swift swiftui init


【解决方案1】:

状态应该以不同的方式初始化——不是按值,而是按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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      在函数式编程中,我们可以跟踪 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
      }
      

      【讨论】:

      • 感谢您的回答。不幸的是,这是不可能的,因为 Doctor 是 Optional 并且可能为零
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2020-10-11
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多