Reputation: 79
class Room: ObservableObject { ... }
Contact: ObservableObject {
var chatRoom: Room
}
class Account: ObservableObject {
var rooms: Room { … }
var contacts: [Contact] {
return rooms.map {
Contact(chatRoom: $0)
}
}
func listenForRoomEvents() {
// Called on instantiation of a Room, this fires self.objectWillChange on room updates and is working properly
}
}
struct RoomView: View {
@ObservedObject var room: Room
}
/ THIS IS WORKING /
struct ParentView: View {
@EnvironmentObject account: Account
var body: some View {
RoomsView(account.rooms)
.onAppear {
self.account.listenForRoomEvents()
}
}
}
struct RoomsView: View {
var rooms: [Room]
var body: some View {
ForEach(rooms) { room in
NavigationLink(destination: RoomView(room: room)) {
RoomListItemView(room: room)
}
}
}
}
/ THIS IS NOT WORKING /
struct ParentView: View {
@EnvironmentObject account: Account
var body: some View {
Child1(contacts: account.contacts)
.onAppear {
self.account.listenForRoomEvents()
}
}
}
struct Child1: View {
@State var selectedContact: Contact?
var contacts: [Contact]
var body: some View {
RoomView(selectedContact.chatRoom)
UserSelectorView(contacts: contacts, selectedUser: $selectedContact) // View allowing selection of a user
}
}
I outlined my setup above; basically, I am instantiating a RoomView object with a Room instance containing all the chat events and other details. Child1 holds a selected contact state variable which is bound to two of its own subviews, one of which allows for the user to select a different contact and such.
What does not make sense to me is that the RoomView renders just fine with all it's events, but in the second solution I have it does not update when new messages come in or when one should be displayed after sending, for instance. I am passing a reference to the same Room object to it, but cannot for the life of me get it to update properly like it does in the first solution.
When I select a new user and go back to the previous one, the messages are all updated as expected.
Here is what I have tried so far:
Upvotes: 0
Views: 439
Reputation: 79
Okay I finally figured this out, I have no idea why this works and it might be a dumb solution; I needed to not only pass the selectedContact as a parameter, but also the room as another parameter. The code in the outline isnt exactly as it is in my source, but if you ever run into a problem where a class variable isnt updating properly in a view try to pass the variable down from higher up in the chain.
Upvotes: 1
Reputation: 2143
Which version of Xcode are you running? If you are running Xcode 12.2 beta2, I'd recommend you to try it with Xcode 12.0.
I saw a similar issue with my code. After wasting a lot of hours, I finally figure it out that Xcode (I was runnig Xcode 12.2 beta2) has a bug.
SwiftUI: Updating an array item does not update the child UI immediately
Upvotes: 0