audulus
(Taylor Holliday)
1
I'm following the steps in this article to improve SwiftUI performance with custom diffing. For now, I'm just returning true in ==:
struct MyView: View, Equatable {
@ObservedObject var model: DataModel
static func == (lhs: Self, rhs: Self) -> Bool {
return true
}
var body: some View { ... lots of stuff ... }
}
I'm using .equatable() to wrap MyView in EquatableView where it's used.
However in the SwiftUI instrument, I still see the entire view rebuilt whenever DataModel changes. And the debugger confirms that body is called. == is also called.
It would seem that customizing diffing can't be used with @ObservedObject. When I remove the @ObservedObject, body isn't called. But without @ObservedObject, I can't bind the UI within my view to my data model (similar issue for @EnvironmentObject).
Anyone know how to accomplish this? thanks!
audulus
(Taylor Holliday)
2
I ended up creating another ObservableObject which only stores the information I need:
class MyViewModel: ObservableObject {
var dataModel: DataModel
var uiSub: Any!
@Published var someState = 0 {
didSet {
dataModel.someStruct.someState
}
}
init(model: DataModel) {
self.dataModel = model
someState = model.someStruct.someState
uiSub = model.$someStruct.sink { [weak self] someStruct in
guard let self = self else { return }
if someStruct.someState != self.someState {
self.someState = someStruct.someState
}
}
}
}
So changing say model.someStruct.someOtherField wouldn't trigger any changes to MyViewModel.
This approach isn't terribly satisfying, but at least I don't have to change my DataModel to optimize SwiftUI. Anyone know a better way?