将@State值委托给子组件

时间:2019-08-03 02:33:57

标签: swift swiftui

一个新的Swift人。试图了解SwiftUI。 我正在尝试创建一个包装文本和文本字段的“字段”组件。这样做的想法是减少代码并拥有一个可以显示字段标题及其对应值的控件。

我不知道如何在控件上分配模型的值。

这是我的模特

import Foundation

class EmployeeModel {

    var FullName: String = "John Doe"
    var JobStartDate: String = ""
    var BornDate: String = ""
    var DepartmentId: Int = 0
    var DepartmentName: String = ""
    var isBossDepartment: Bool = false
    var JobPositionId: Int = 0
    var JobPositionName: String = ""
    var PersonalDocNumber: String = ""
    var Password: String = ""

    init() {
    }

}

在视图的某些部分...

struct EmployeeView : View {
    @State private var Employee = EmployeeModel()

    var body : some View {
        Field("Full Name", $Employee.FullName)
    }
}

这是我要实现的自定义组件。

struct Field : View {
    private var caption: String = ""
    @State private var controlValue: String = ""

    init(caption: String, value: String) {
        self.caption = caption
        controlValue = value
    }

    var body : some View {
        VStack {
            Text(self.caption)
            TextField($controlValue)
                .textFieldStyle(.roundedBorder)
        }
    }
}

当前我收到一条消息

在EmployeeView的Field实现上,“绑定”不能转换为“字符串”

1 个答案:

答案 0 :(得分:1)

在详细讨论问题之前,请注意,按照约定,类型(类,结构,枚举等)应以大写字母开头,而对象和值应以小写字母(或下划线)开头。如果不遵循该约定,就会使每个人都难以理解该代码,就像其他人所期望的那样。

现在,在您的代码上,有一些改进:

  1. controlValue必须声明为@Binding
  2. @Binding属性不应具有初始值,因为它们应该由调用方传递。
  3. 如果您声明属性为非私有,则不需要初始化程序。没问题,但是如果您使用初始化程序,则需要执行多个更改(请参见下面的代码)。
  4. 您的TextField在beta 5中使用了不建议使用且已终止的初始化程序。
struct EmployeeModel {

    var fullName: String = "John Doe"
    var jobStartDate: String = ""
    var bornDate: String = ""
    var departmentId: Int = 0
    var departmentName: String = ""
    var isBossDepartment: Bool = false
    var jobPositionId: Int = 0
    var jobPositionName: String = ""
    var personalDocNumber: String = ""
    var password: String = ""

    init() {
    }

}

struct EmployeeView : View {
    @State private var employee = EmployeeModel()

    var body : some View {
        Field(caption: "Full Name", value: $employee.fullName)
    }
}

struct Field : View {
    private var caption: String = ""
    @Binding private var controlValue: String

    init(caption: String, value: Binding<String>) {
        self.caption = caption
        self._controlValue = value
    }

    var body : some View {
        VStack {
            Text(self.caption)
            TextField("", text: $controlValue)
                .textFieldStyle(.roundedBorder)
        }
    }
}