SwiftUI ObservedObject无法在View中更新

时间:2020-11-04 17:17:25

标签: swift swiftui combine

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
}

/ 这正在工作 /

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)
            }
        }
    }
}

/ 这不起作用 /

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
    }
}

我在上面概述了我的设置;基本上,我将使用包含所有聊天事件和其他详细信息的Room实例实例化RoomView对象。 Child1拥有一个选定的联系人状态变量,该变量绑定到其自己的两个子视图,其中一个允许用户选择其他联系人等等。

对我来说没有什么意义的是,RoomView可以很好地处理所有事件,但是在第二种解决方案中,当有新消息传入或发送后应该显示消息时,我不会更新它。我正在向其传递对同一Room对象的引用,但是我一生都无法像在第一个解决方案中那样正确地对其进行更新。

当我选择一个新用户并返回上一个用户时,消息将按预期更新。

这是我到目前为止尝试过的:

  • 使Contact.chatRoom成为已发布的变量,然后每当chatRoom进行调用时,都要调用self.objectWillChange.send()

2 个答案:

答案 0 :(得分:0)

您正在运行哪个版本的Xcode?如果您正在运行Xcode 12.2 beta2,建议您将其与Xcode 12.0一起尝试。

我的代码也遇到了类似的问题。浪费了很多时间之后,我终于弄清楚了Xcode(我当时运行的是Xcode 12.2 beta2)存在一个错误。

SwiftUI: Updating an array item does not update the child UI immediately

答案 1 :(得分:0)

好吧,我终于弄清楚了,我不知道为什么这样做,这可能是一个愚蠢的解决方案。我不仅需要将selectedContact作为参数传递,还需要将room作为另一个参数传递。大纲中的代码与我的源代码中的代码不完全相同,但是如果您遇到问题,即视图中的类变量无法正确更新,请尝试将变量从链中的较高位置向下传递。