Why an ObservedObject array is not updated in my SwiftUI application?

前端 未结 4 1464
被撕碎了的回忆
被撕碎了的回忆 2020-11-30 00:53

I\'m playing with SwitUI, trying to understand how ObservableObject works. I have an array of Person objects. When I add a new Person into the array, it is reloaded in my Vi

4条回答
  •  孤独总比滥情好
    2020-11-30 01:25

    For those who might find it helpful. This is a more generic approach to @kontiki 's answer.

    This way you will not have to be repeating yourself for different model class types

    import Foundation
    import Combine
    import SwiftUI
    
    class ObservableArray: ObservableObject {
    
        @Published var array:[T] = []
        var cancellables = [AnyCancellable]()
    
        init(array: [T]) {
            self.array = array
    
        }
    
        func observeChildrenChanges() -> ObservableArray {
            let array2 = array as! [T]
            array2.forEach({
                let c = $0.objectWillChange.sink(receiveValue: { _ in self.objectWillChange.send() })
    
                // Important: You have to keep the returned value allocated,
                // otherwise the sink subscription gets cancelled
                self.cancellables.append(c)
            })
            return self as! ObservableArray
        }
    
    
    }
    
    class Person: ObservableObject,Identifiable{
        var id: Int
        @Published var name: String
    
        init(id: Int, name: String){
            self.id = id
            self.name = name
        }
    
    } 
    
    struct ContentView : View {
        //For observing changes to the array only. 
        //No need for model class(in this case Person) to conform to ObservabeObject protocol
        @ObservedObject var mypeople: ObservableArray = ObservableArray(array: [
                Person(id: 1, name:"Javier"),
                Person(id: 2, name:"Juan"),
                Person(id: 3, name:"Pedro"),
                Person(id: 4, name:"Luis")])
    
        //For observing changes to the array and changes inside its children
        //Note: The model class(in this case Person) must conform to ObservableObject protocol
        @ObservedObject var mypeople: ObservableArray = try! ObservableArray(array: [
                Person(id: 1, name:"Javier"),
                Person(id: 2, name:"Juan"),
                Person(id: 3, name:"Pedro"),
                Person(id: 4, name:"Luis")]).observeChildrenChanges()
    
        var body: some View {
            VStack{
                ForEach(mypeople.array){ person in
                    Text("\(person.name)")
                }
                Button(action: {
                    self.mypeople.array[0].name="Jaime"
                    //self.mypeople.people.append(Person(id: 5, name: "John"))
                }) {
                    Text("Add/Change name")
                }
            }
        }
    }
    
    

提交回复
热议问题