我正在探索SwiftUI,但遇到了一些我无法弄清楚的事情。
我已经创建了一个可以取如上述上出现数据的容器视图此柱,但不是完全地改变呈现视图引用的对象,我只加载它的一些属性。
加载程序是ObservableObject
容器视图所观察到的。当加载器指示其值已更改时,容器视图将重新加载其body
属性,并显示带有新数据的渲染视图。但是,当需要加载的对象是一个类时,并非该body
属性中的所有子视图都会重新加载。
这是我的实现的一些“伪”代码。
protocol ValueLoader: Combine.ObservableObject {
associatedtype Value
var data: Value { get set }
func load()
}
struct ValueLoadingContainerView<ValueConsumer: View,
ValueContainer: ValueLoader>: View {
@ObservedObject var valueLoader: ValueContainer
let containedView: (ValueContainer.Value) -> ValueConsumer
init(_ loader: ValueContainer,
@ViewBuilder contained: @escaping (ValueContainer.Value) -> ValueConsumer) {
self.valueLoader = loader
self.containedView = contained
}
var body: some View {
containedView(valueLoader.data)
.onAppear(perform: load)
}
private func load() {
self.valueLoader.load()
}
}
class Object {
let id: String
var title: String?
func load(from ...) {
self.title = ...
}
}
struct ConcreteLoader: ValueLoader {
@Published var data: Object
func load() {
guard shouldLoad() else { return } // To prevent infinite recursion
...
// self.objectWillChange is synthesised by conforming to
// ObservableObject and having a property with @Published
self.objectWillChange.send()
self.data.load(from: ...)
}
}
struct ObjectRenderingView: View {
let object: Object
var body: some View {
Text(object.title ?? "ObjectRenderingView is waiting...")
}
}
let object = Object(id: "1", title: nil)
ValueLoadingContainer(ConcreteLoader(object),
contained: { obj in
Text(obj.title ?? "Text is waiting...") // 1
Divider()
ObjectRenderingView(object: obj) // 2
})
加载程序加载后,其属性将再次用该对象object
调用传递的@ViewBuilder
闭包,但是现在加载了其属性。
如果添加print
语句,则可以清楚地看到该contained
@ViewBuilder
闭包被调用了两次:一次是使用卸载对象,一次是使用加载对象。这些是相同的对象,但是第二次,属性已加载。
该Text
标签(1)正确更新,更改“文本在等待......”的实际标题,但ObjectRenderingView
(2)不更新其子视图。
该init
的ObjectRenderingView
被称为新数据,但绝不会在访问的身体属性。这向我表明SwiftUI认为数据没有更改,因此不需要重新呈现。
我想我知道为什么它不起作用:的身份obj
没有更改,因此SwiftUI认为ObjectRenderingView
不需要重新加载。由于值的标识obj.title
已从更改nil
为实际标题,因此Text
将重新加载视图。我不知道的是如何使SwiftUI也重新加载ObjectRenderingView
。
谢谢!
它应该是一个值类型。请查看Xcode中ObservedObject的文档。
如果
Value
不是值语义,Binding
则未指定使用结果的任何视图的更新行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句