Установите начальное значение для TextField в SwiftUI - сравните новое и старое значение - PullRequest
0 голосов
/ 24 апреля 2020

Я видел много примеров и учебных пособий о том, как использовать пустой 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 ]

1 голос
/ 24 апреля 2020

Чтобы инициализировать текстовое поле значением из вашей модели, вам нужно определить свой собственный инициализатор, используйте 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")
    }
}
0 голосов
/ 24 апреля 2020

как насчет чего-то вроде этого тестового кода. Ключ должен использовать «ObservableObject»:

import SwiftUI


class MyModel: ObservableObject {
@Published var model = "model1"
}

struct ContentView: View {

@ObservedObject var myModel = MyModel()
@State var editedValue = ""

var body: some View {
    NavigationView {
        VStack(alignment: .leading, spacing: 20) {
            Group{
                Text("Some label")
                TextField("Placeholder text", text: Binding<String>(
                    get: { self.editedValue },
                    set: {
                        self.editedValue = $0
                        self.myModel.model = self.editedValue
                })).onAppear(perform: loadData)
            }
            Divider()

            NavigationLink(destination: Text("the nex page")) {
                Text("Click Me To Display The next View")
            }

            // 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
                self.myModel.model = self.editedValue
            },label: {
                Text("SAVE")
            })
        }
    }.navigationViewStyle(StackNavigationViewStyle())
}

func loadData() {
    self.editedValue = myModel.model
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...