简体   繁体   中英

SwiftUI ObservedObject not updating in View

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:

  • Making Contact.chatRoom a Published variable, and then calling self.objectWillChange.send() whenever chatRoom does

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM