使用 SwiftUI 在 UserDefaults 中保存来自 TextField 的字符串

osc*_*car 1 string textfield userdefaults swiftui

如何使用SwiftUI将来自 TextField 的字符串存储在 UserDefaults 中?

我已经看过有关如何在 UserDefaults 中保存切换状态的教程,这看起来很有希望,但我无法弄清楚如何使用相同的想法来存储来自 TextField 的内容:https : //www.youtube。 com/watch?v=nV-OdfQhStM&list=PLerlU8xuZ7Fk9zRMuh7JCKy1eOtdxSBut&index=3&t=329s

我仍然希望能够通过在 TextField 中键入新文本来更新字符串,但除非我这样做,否则我希望在视图中保留该字符串。在更改页面和完全退出应用程序时。

sup*_*cio 5

对于这样的事情,我建议你使用.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)
    }
}
Run Code Online (Sandbox Code Playgroud)

.debounce出版商的文件说:

当您想等待上游发布者的事件传递暂停时,请使用此运算符。例如,从文本字段调用发布者的 debounce 以仅在用户暂停或停止输入时接收元素。当他们再次开始打字时,去抖动会保持事件传递,直到下一次暂停。

你真的不想在用户UserDefaults 每次输入内容时保存文本(即他/她输入的每个字符)。您只希望文本最终保存到 UserDefaults。debounce 发布者根据您在 debounce init 中设置的时间(在上面的示例中为 0.2 秒)等待用户停止输入,然后将事件转发给sink实际保存文本的订阅者。当您有很多事件(例如在文本字段中键入新文本)可能触发“重”操作(无论您能想到什么:与 CoreData、网络调用等相关的内容)时,请始终使用去抖动发布器。