I have a structure like this:
contentView {
navigationView {
foreach {
NavigationLink(ViewA(id: id))
}
}
}
/// where ViewA contains an request trigger when it appears
struct ViewA: View {
@State var filterString: String = ""
var id: String!
@ObservedObject var model: ListObj = ListObj()
init(id: String) {
self.id = id
}
var body: some View {
VStack {
SearchBarView(searchText: $filterString)
List {
ForEach(model.items.filter({ filterString.isEmpty || $0.id.contains(filterString) || $0.name.contains(filterString) }), id: \.id) { item in
NavigationLink(destination: ViewB(id: item.id)) {
VStack {
Text("\(item.name) ")
}
}
}
}
}
.onAppear {
self.model.getListObj(id: self.id) //api request, fill data and call objectWillChange.send()
}
}
}
ViewB
has the same code as ViewA
: It receives an id, stores and requests an API to collect data.
But the viewB
list is not being refreshed.
I also noticed that viewB
's model
property
@ObservedObject var model: model = model()
was instantiated multiple times.
Debugging, I found that every navigationLink instantiates its destination even before it is triggered. That's not a problem usually, but in my case i feel like the ViewB
model is being instantiated 2 times, and my onAppear
call the wrong one, reason why self.objectWillChange.send()
not refreshing my view.
If your @ObservedObject
is being initialized multiple times, it is because the owner of the object is refreshed and recreated every time it has state changes. Try to use @StateObject
if your app is iOS 14 and above. It prevents the object from being recreated when the view refreshes.
https://developer.apple.com/documentation/swiftui/stateobject
When a view creates its own @ObservedObject instance it is recreated every time a view is discarded and redrawn. On the contrary a @State variable will keep its value when a view is redrawn. A @StateObject is a combination of @ObservedObject and @State - the instance of the ViewModel will be kept and reused even after a view is discarded and redrawn
What is the difference between ObservedObject and StateObject in SwiftUI