Я работаю над экраном SwiftUI, который обновляет несколько значений в UserDefaults, чтобы приложение сохраняло основные настройки. Я пытаюсь использовать Combine и SwiftUI, так как это родное приложение WatchOS.
Базовое представление дает мне ошибку, которая, как мне кажется, связана с propertyWrapper для UserDefaults, но так как я никогда не работал сpropertyWrappers (или Combine в этом отношении) Я не могу понять, как это исправить.
вот оболочка свойства:
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)
}
}
}
Как вы можете видеть, она охватывает все пары ключей для пользовательских значений.
Мой класс аналогично очень прост, состоящий из двухbools and double
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)
}
}
}
Проблема в том, что в SwiftUI я использую TextField для ввода и обновления двойного значения
@ObservedObject var setup: Setup = Setup()
private var currencyFormatter: NumberFormatter = {
let f = NumberFormatter()
f.numberStyle = .currency
return f
}()
var body: some View {
ScrollView{
HStack{
TextField(self.$setup.someValueDouble,
formatter: currencyFormatter,
placeholder: "0.00",
onEditingChanged: {_ in
print("editing changed")
},
onCommit: {
print("updated")
}
)
}
HStack{
Button(action: {
self.setup.opt1Enabled = false
self.setup.opt2Enabled = true
} ) {
Text(verbatim: "Opt 1")
.font(Font.system(size: 16, design: Font.Design.rounded))
}
.background(setup.opt1Enabled ? Color.blue : Color.gray)
.disabled(self.setup.opt1Enabled)
.cornerRadius(5)
Button(action: {
self.setup.opt1Enabled = true
self.setup.opt2Enabled = false
}) {
Text(verbatim: "Opt 2")
}
.background(setup.opt2Enabled ? Color.blue : Color.gray)
.disabled(self.setup.opt2Enabled)
}
}
}
}
Затем TextField выдает сообщение о том, чтоОбщий параметр «Метка» не может быть выведен. Xcode предлагает «исправить» это, но конечным результатом является TextField, который явно неполон, но единственным представлением во всей этой программе является «ContentView», который недопустим.