Сохранить строку из TextField в UserDefaults с SwiftUI - PullRequest
0 голосов
/ 21 сентября 2019

Как можно сохранить строку из TextField в UserDefaults с помощью SwiftUI ?

Я видел этот учебник о том, как сохранить состояние переключателя в UserDefaults, и это выглядит многообещающе,но я не могу понять, как использовать ту же идею для хранения содержимого из TextField: https://www.youtube.com/watch?v=nV-OdfQhStM&list=PLerlU8xuZ7Fk9zRMuh7JCKy1eOtdxSBut&index=3&t=329s

Я все еще хочу иметь возможность обновить строку, набрав новый текст в TextField, но еслиЯ делаю это, я хочу, чтобы строка была сохранена в представлении.Как при смене страницы, так и при полном выходе из приложения.

Ответы [ 2 ]

1 голос
/ 21 сентября 2019

Вы можете создать пользовательскую привязку, как описано здесь, и вызывать UserDefaults.standard.set, когда текстовая привязка установлена.

struct ContentView: View {
    @State var location: String = ""

    var body: some View {
        let binding = Binding<String>(get: {
            self.location
        }, set: {
            self.location = $0
            // Save to UserDefaults here...
        })

        return VStack {
            Text("Current location: \(location)")
            TextField("Search Location", text: binding)
        }

    }
}

Скопировано из ответа на 'TextField изменения в SwiftUI'

0 голосов
/ 21 сентября 2019

Для подобных вещей я предлагаю вам использовать .debounce издателя.

import SwiftUI
import Combine

class TestViewModel : ObservableObject {
    private static let userDefaultTextKey = "textKey"
    @Published var text = UserDefaults.standard.string(forKey: TestViewModel.userDefaultTextKey) ?? ""
    private var canc: AnyCancellable!

    init() {
        canc = $text.debounce(for: 0.2, scheduler: DispatchQueue.main).sink { newText in
            UserDefaults.standard.set(newText, forKey: TestViewModel.userDefaultTextKey)            
        }
    }

    deinit {
        canc.cancel()
    }
}

struct ContentView: View {
    @ObservedObject var viewModel = TestViewModel()

    var body: some View {
        TextField("Type something...", text: $viewModel.text)
    }
}

Документация издателя .debounce гласит:

Используйте этот оператор, если вы хотите дождаться паузы в доставке событий от вышестоящего издателя.Например, вызовите debounce на издателе из текстового поля, чтобы получать элементы только тогда, когда пользователь делает паузу или прекращает печатать.Когда они снова начинают печатать, отладка удерживает доставку события до следующей паузы.

Вы на самом деле не хотите сохранять текст в UserDefaults каждый раз, когда пользовательчто-то печатает (т.е. для каждого персонажа, который он / она печатает).Вы просто хотите, чтобы текст был в конечном итоге сохранен в UserDefaults.Издатель debounce ожидает, пока пользователь прекратит печатать в соответствии с временем, установленным вами в init debounce (в примере выше 0,2 с), а затем перенаправит событие подписчику sink, который фактически сохранит текст.Всегда используйте издателя debounce, когда у вас много событий (например, новый текст, набранный в текстовом поле), которые могут вызвать «тяжелые» операции (что бы вы ни думали: что-то, связанное с CoreData, сетевые вызовы и т. Д.).

...