如何使自定义属性包装可绑定,可能与@State绑定



我创建了一个自定义属性包装器,它作为文件的setter和getter来写入和读取文件。

@propertyWrapper struct Specifier<Value> {
let key: String
let defaultValue: Value
let plistPath: String

var prefs: NSDictionary {
NSDictionary(contentsOfFile: plistPath) ?? NSDictionary()
}
var wrappedValue: Value {
get {
return prefs.value(forKey: key) as? Value ?? defaultValue
}
set {
prefs.setValue(newValue, forKey: key)
prefs.write(toFile: plistPath, atomically: true)
}
}
}

我现在想在这样的设置视图中使用这个:

struct PrefsView: View {
@Specifier<Bool>(key: "enable", defaultValue: true, plistPath: "/Library/path/to/Prefs.plist") private var enable
var body: some View {
Form {
Toggle("Enable", isOn: $enable)
}
}
}

我收到以下错误:

Cannot find '$enable' in scope

如何实现对文件进行写入和读取以设置和获取变量,同时又允许其绑定到值的效果?

注意:我的项目不需要是";App Store Legal";

您的属性包装返回Bool,而不是Toggle所需的Binding<Bool>

您可以指定projectedValue(正如NewDev建议的那样(-这将允许您使用$:访问Binding

@propertyWrapper struct Specifier<Value> {
...
var wrappedValue: Value {
get {
projectedValue.wrappedValue
}
set {
projectedValue.wrappedValue = newValue
}
}

var projectedValue: Binding<Value> {
.init(get: {
prefs.value(forKey: key) as? Value ?? defaultValue
}, set: {
prefs.setValue($0, forKey: key)
prefs.write(toFile: plistPath, atomically: true)
})
}
}
struct ContentView: View {
@Specifier(key: "enable", defaultValue: true, plistPath: "/Library/path/to/Prefs.plist") private var enable
var body: some View {
Form {
Toggle("Enable", isOn: $enable)
Text(String(enable))
}
}
}

或者,您可以将wrappedValue的返回类型更改为Binding<Bool>:

@propertyWrapper struct Specifier<Value> {
...
var wrappedValue: Binding<Value> {
.init(get: {
prefs.value(forKey: key) as? Value ?? defaultValue
}, set: {
prefs.setValue($0, forKey: key)
prefs.write(toFile: plistPath, atomically: true)
})
}
}
struct ContentView: View {
@Specifier(key: "enable", defaultValue: true, plistPath: "/Library/path/to/Prefs.plist") private var enable
var body: some View {
Form {
Toggle("Enable", isOn: enable) // access as a Binding
Text(String(enable.wrappedValue)) // access as a Bool
}
}
}

最新更新