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

时间:2020-04-23 22:01:59

标签: swiftui

我已经看到了许多示例和教程,这些示例和教程介绍了如何使用空的TextField来收集新值,但是没有一个例子说明如何使用TextField编辑值。

在我的用例中,我希望用我的视图模型中的数据预填充/预填充TextField,然后在用户编辑数据时,应启用“保存”按钮。在我的表单中,我还具有一个导航链接,该链接指向一个子页面,用户可以在其中从列表中选择某些内容,然后将其路由回表单。

只要我使用一个空字段,它的行为就可以描述;用户可以在字段中输入临时内容,导航到子页面,并且temp值仍然与离开时的状态相同。

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

2 个答案:

答案 0 :(得分:4)

要使用模型中的值初始化文本字段,您需要定义自己的初始化程序,并将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")
    }
}

答案 1 :(得分:0)

像这样的测试代码怎么样。关键是要使用“ ObservableObject”:

        const reminderRequest = {
            trigger: {
                type: 'SCHEDULED_RELATIVE',
                offsetInSeconds: '10',
            },
            alertInfo: {
                spokenInfo: {
                    content: [{
                        locale: "en-US",
                        text: "Testing Reminder", 
                        ssml: "<speak>Testing Reminder <audio src='https://vishalsholkaybucket.s3.amazonaws.com/uk_21042020.mp3' /></speak>"
                    }],
                },
            },
            pushNotification: {
                status: 'ENABLED',
            },
        };