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

Save string from TextField in UserDefaults with SwiftUI

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

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

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

您可以按照此处所述创建自定义绑定,并在设置文本绑定时调用 UserDefaults.standard.set

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

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

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

    }
}

对于此类事情,我建议您使用 .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 发布者文档说:

Use this operator when you want to wait for a pause in the delivery of events from the upstream publisher. For example, call debounce on the publisher from a text field to only receive elements when the user pauses or stops typing. When they start typing again, the debounce holds event delivery until the next pause.

你真的不想在 UserDefaults 每次 用户键入内容时保存文本(即每个字符 he/she 类型) .您只想将文本最终保存到 UserDefaults。 debounce 发布者根据你在 debounce init 中设置的时间(在上面的例子中是 0.2 秒)等待用户停止输入,然后将事件转发给实际保存文本的 sink 订阅者。当你有很多可能触发 "heavy" 操作的事件(例如在文本字段中键入的新文本)时,请始终使用 debounce 发布者(无论你能想到什么:与 CoreData、网络调用等相关的东西) .