swift - 如何使自定义属性包装器可绑定,可能使用@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
不是.Binding<Bool>
Toggle
您可以指定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
}
}
}
推荐阅读
- c# - C# 使用其他方法的更新数组 - 创建控制台游戏“Nim”
- vhdl - vhdl 中没有实际的常量接口
- python - 具有可变数量参数的函数
- javascript - 滚动方向错误 机车滚动
- javascript - js:页面加载时显示第一帧视频
- elasticsearch - ElasticSearch:如果文档中存在字段,则在 script_score 函数中执行余弦相似度
- python - 用鼠标单击轮廓但只能找到 1 个轮廓?
- reactjs - 如何存储 socket-io-client 实例以通过应用程序访问
- html - 如何创建一个里面有文字的圆圈
- python - 将 Discord.py 作为 asyncio 子进程运行