【发布时间】:2020-04-25 08:28:21
【问题描述】:
我有一个看起来像这样的模型类型:
enum State {
case loading
case loaded([String])
case failed(Error)
var strings: [String]? {
switch self {
case .loaded(let strings): return strings
default: return nil
}
}
}
class MyApi: ObservableObject {
private(set) var state: State = .loading
func fetch() {
... some time later ...
self.state = .loaded(["Hello", "World"])
}
}
我正在尝试使用它来驱动 SwiftUI 视图。
struct WordListView: View {
@EnvironmentObject var api: MyApi
var body: some View {
ZStack {
List($api.state.strings) {
Text($0)
}
}
}
}
正是在这里,我的假设失败了。我正在尝试获取要在我的List 加载时呈现的字符串列表,但它不会编译。
编译器错误是Generic parameter 'Subject' could not be inferred,经过一番谷歌搜索后告诉我绑定是双向的,因此不适用于我的private(set) 和State 枚举上的var 只读。
这似乎没有任何意义 - 视图无法告诉 api 它是否正在加载,这绝对应该是单向数据流!
我想我的问题是要么
- 有没有办法在 SwiftUI 中获得单向绑定 - 即某些 UI 将根据无法更改的值进行更新。
或
- 我应该如何构建这段代码!很可能我编写的代码风格不适用于 SwiftUI,但我在网上看到的所有教程都巧妙地忽略了加载/错误状态等内容。
【问题讨论】:
-
列表不需要绑定,为什么你使用
List($api.state.strings)而不是,我希望,List(api.state.strings)? -
因为 (a) 我是 SwiftUI 的新手,并且 (b) 当我这样做时,它并没有更新 UI。应该这样做吗?
-
我愿意,并将
state设为@Published以更新视图 -
@Asperi 你应该把这个作为答案,所以我可以勾选它:) 我没有意识到对可观察对象的任何更改都会触发重绘,即使它们不是绑定。现在完美运行,谢谢!