【问题标题】:Save string from TextField in UserDefaults with SwiftUI使用 SwiftUI 在 UserDefaults 中保存 TextField 中的字符串
【发布时间】:2020-01-22 03:55:58
【问题描述】:

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

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

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

【问题讨论】:

标签: string textfield swiftui userdefaults


【解决方案1】:

对于此类事情,我建议您使用.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 发布者根据您在 debounce init 中设置的时间(在上面的示例中为 0.2 秒)等待用户停止输入,然后将事件转发给实际保存文本的 sink 订阅者。当您有很多可能触发“繁重”操作的事件(例如,在文本字段中键入新文本)时(无论您能想到什么:与 CoreData、网络调用等相关的事情),请始终使用 debounce 发布者。

【讨论】:

  • 感谢您的评论!我已经测试了代码,但是当应用程序重新启动时,我仍然遇到用户输入被删除的问题。保存到 UserDefaults 应该没问题,因为这个应用程序的输入每周会发生一次或更少,所以数据负载不应该太重。如果可能的话,我仍然想要比保存到 UserDefaults 更好的解决方案,因为我是 SwiftUI 编码的新手。
  • @oscar 我编辑了我的答案,以便您的用户在应用启动时看到他/她之前输入的文本。只需读取您之前保存的用户默认值即可。
【解决方案2】:

您可以按照此处所述创建自定义绑定,并在设置文本绑定时调用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)
        }

    }
}

Copied from answer to 'TextField changes in SwiftUI'

【讨论】:

  • 请不要发布仅链接的答案。虽然它们可能是正确的,但如果链接更改/关闭,您的答案的完整性将受到影响。尝试在您的答案中包含此链接中的基本部分。
  • 感谢您的回复!我的问题现在是在您写“保存到 UserDefaults 此处...”的地方写什么。这是我感到困惑的部分。我希望 TextField 中的输入数据保留在视图中,即使在关闭应用程序之后也是如此。
猜你喜欢
  • 2020-06-02
  • 2020-07-21
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2020-04-03
  • 2022-12-06
  • 2020-06-10
  • 2022-01-18
相关资源
最近更新 更多