在 SwiftUI 中为 TextField 设置初始值 - 比较新旧值

And*_*ndi 3 swiftui

我看过很多关于如何使用空 TextField 收集新值的示例和教程,但没有一个显示如何使用 TextField 来编辑值。

在我的用例中,我希望 TextField 预先填充/预填充来自我的视图模型的数据,然后当用户编辑数据时,应该启用保存按钮。在我的表单中,我还有一个导航链接,它通向一个子页面,用户可以在其中从列表中选择一些内容,然后返回到表单。

只要我使用一个空字段,它就会像描述的那样运行;用户可以在字段中输入临时内容,导航到子页面,临时值仍然和他离开时一样。

struct TextFieldDemo: View {

    var model:String    // Actual a more complex view model
    @State var editedValue:String = ""

    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            Group{
                Text("Some label")
                TextField("Placeholder text", text: $editedValue)
            }
            Divider()
            Text("Some navigation link to push in a page where " +
                "the user can select something from a list and click back...")

            // If the user starts to edit the textfield - follows a navigation link and comes back
            // he should be able to continue edit the field where he left of - the text field should
            // not have been reset to the original value.

            Button(action: {
                // Call some save function in the ViewModel
                },label: {
                    Text("SAVE")
                }
            ).disabled(model == editedValue)
        }.onAppear(){
            // I could have done something like:
            //   self.editedValue = model
            // but it seems like this will fire if the user navigates into the described page and reset
            // the TextField to the model value.
        }
    }
}

struct TextFieldDemo_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldDemo(model: "The old value")
    }
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*Sam 9

要使用模型中的值初始化文本字段,您需要定义自己的初始化程序并使用vars的State(wrappedValue:)初始化程序@State

struct TextFieldDemo: View {

    var model:String    // Actual a more complex view model
    @State var editedValue: String

    init(model: String) {
        self.model = model
        self._editedValue = State(wrappedValue: model) // _editedValue is State<String>
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            Group{
                Text("Some label")
                TextField("Placeholder text", text: $editedValue)
            }
            Divider()
            Text("Some navigation link to push in a page where " +
                "the user can select something from a list and click back...")

            // If the user starts to edit the textfield - follows a navigation link and comes back
            // he should be able to continue edit the field where he left of - the text field should
            // not have been reset to the original value.

            Button(action: {
                // Call some save function in the ViewModel
                },label: {
                    Text("SAVE")
                }
            ).disabled(model == editedValue)
        }.onAppear(){
            // I could have done something like:
            //   self.editedValue = model
            // but it seems like this will fire if the user navigates into the described page and reset
            // the TextField to the model value.
        }
    }
}

struct TextFieldDemo_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldDemo(model: "The old value")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 那是一些做作的废话。不是你对它的解释,事实上这是唯一的方法。苹果,这让人感觉很被黑客攻击。你在想什么?下划线、wrappedValue 和 State 包装器。啊。 (8认同)
  • @ChrisH,你不知道我有多少次有同样的感觉。我发现属性包装器非常酷而且功能强大,随着 Swift 新版本的出现,你可以在越来越多的环境中使用它们,但 SwiftUI 的某些部分的做事方式确实很糟糕。 (3认同)