我正在处理一个SwiftUI屏幕,该屏幕更新UserDefaults中的多个值,以允许该应用保留基本设置。我正在尝试使用Combine和SwiftUI,因为这是本地的WatchOS应用。
基本视图给了我一个错误,我认为它与UserDefaults的propertyWrapper有关,但是由于我从未使用过propertyWrappers(或与此相关的Combine),因此我无法弄清楚该如何解决。
这是属性包装器:
wikibase_item
如您所见,它包装了UserDefaults的所有密钥对。
我的课程同样非常简单,由两个布尔和一个双
组成import Foundation
@propertyWrapper
struct UserDefault<T> {
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
UserDefaults(suiteName: "group.com.my.app")!.value(forKey: key) as? T ?? defaultValue
} set {
UserDefaults(suiteName: "group.com.my.app")!.set(newValue, forKey: key)
}
}
}
问题在于,在SwiftUI中,我使用TextField允许输入和更新双精度值
import SwiftUI
import Foundation
import Combine
class Setup: ObservableObject {
private var notificationSubscription: AnyCancellable?
let objectWillChange = PassthroughSubject<Setup,Never>()
@UserDefault("keyOpt1Enabled", defaultValue: false)
var opt1Enabled: Bool {
willSet{
objectWillChange.send(self)
}
}
@UserDefault("keyOpt2Enabled", defaultValue: false)
var opt2Enabled: Bool {
willSet{
objectWillChange.send(self)
}
}
@UserDefault("keyValueDouble", defaultValue: Double(0.00))
var someValueDouble: Double {
willSet{
objectWillChange.send(self)
}
}
init() {
notificationSubscription = NotificationCenter.default.publisher(for: UserDefaults.didChangeNotification).sink { _ in
self.objectWillChange.send(self)
}
}
}
然后,TextField给出消息,提示无法推断通用参数“ Label”。 Xcode提供了“修复”此功能,但最终结果是TextField,这显然是不完整的,但是在整个程序中唯一的视图是“ ContentView”,这是无效的。
答案 0 :(得分:1)
问题在于TextField
的初始化程序首先将String
作为其占位符,然后才将其绑定到其值,因此它应大致如下:
TextField("Placeholder",
value: self.$setup.someValueDouble,
formatter: currencyFormatter,
onEditingChanged: { _ in },
onCommit:{})
.keyboardType(.numberPad)
您可能想了解有关TextFields和Formatter的更多信息,因为它似乎是一个棘手的主题。