我有一个@Published
值的视图模型的情况。现在,当我构建UI时,我想在每次发布值改变时通过首选项发送一个值。我遇到的问题是,我不知道如何让SwiftUI观看发布的值并发送首选项。
在下面的代码中,我已经尽力简化了这个问题。
首选项重点:
struct NewValueKey: PreferenceKey {
static var defaultValue: String? = nil
static func reduce(value: inout String?, nextValue: () -> String) {
value = nextValue()
}
}
发布对象:
public class SomeViewModel: ObservableObject {
@Published public var value: String?
}
在Swift UI视图中:
.onReceive(viewModel.$value) { _ in
let newValue = "abc"
Color.clear.preference(key: NewValueKey.self, value: newValue)
}
但是我得到了各种各样的错误,比如没有使用首选项的结果,等等。问题是,我需要执行一些代码来构建我想要发送的值,所以我不能只转发我收到的值。我也考虑过使用@State
属性作为某种中介,但我不确定如何将它们连接在一起。
有什么建议吗?
将value
直接注入到附在被修改的上下文(即视图)的preference
修饰符中就足够了。你不需要.onReceive
修饰符,因为更新后的值会直接激活.preference
修饰符)。
使用Xcode 13.3/iOS 15.4测试
这是主要部分的快照
Button("Generate") {
vm.value = String(Int.random(in: 0...9))
}
.preference(key: NewValueKey.self, value: vm.value) // << here !!
完整的发现报告和代码在这里
不清楚您想要什么,但请确保您的视图中有这样的内容,或等效的@ObservedObject
:
@StateObject var viewModel = SomeViewModel()
也: struct NewValueKey: PreferenceKey {
static var defaultValue: String = "" // <-- here
static func reduce(value: inout String, nextValue: () -> String) { // <-- here
value = nextValue()
}
}
和去掉警告:
.onReceive(viewModel.$value) { _ in
let newValue = "abc"
let _ = Color.clear.preference(key: NewValueKey.self, value: newValue) // <-- here
}
或
.onReceive(viewModel.$value) { val in
if let newValue = val {
let _ = Color.clear.preference(key: NewValueKey.self, value: newValue) // <-- here
}
}