View refreshing not triggered when ObservableObject is inherited in SwiftUI

杀马特。学长 韩版系。学妹 提交于 2020-06-17 07:24:10

问题


ContentView2 view is not refreshed when model.value changes, if Model conforms to ObservableObject directly instead of inheriting SuperModel then it works fine

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    @Published var value = ""
}

struct ContentView2: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}

回答1:


Here is working variant of your example. See that to be able to work, not only chaining the publishers is required, but at least one Published property. So or so, it could help in some scenario.

import SwiftUI

class SuperModel: ObservableObject {
    // this is workaround but not real trouble.
    // without any value in supermodel there is no real usage of SuperModel at all
    @Published var superFlag = false
}

class Model: SuperModel {
    @Published var value = ""
    override init() {
        super.init()
        _ = self.objectWillChange.append(super.objectWillChange)
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

changing the code to

var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text(model.superFlag.description)
            Button("change super flag") {
                self.model.superFlag.toggle()
            }
        }

    }

you can see how to use even your supermodel at the same time




回答2:


Use ObjectWillChange to solve the problem specified.

Here is the working code:

import SwiftUI

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    var value: String = "" {
        willSet { self.objectWillChange.send() }
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text("Model Value1: \(model.value)")
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text("Model Value2: \(model.value)")
        }
    }
}



回答3:


This really looks like heavy defect.

class SuperModel: ObservableObject {
}

class Model: SuperModel {
    @Published var value = ""
}

as I see the value is changed and keep new one as expected, but DynamicProperty feature does not work

The following variant works for me (Xcode 11.2 / iOS 13.2)

class SuperModel: ObservableObject {
    @Published private var stub = "" // << required !!!
}

class Model: SuperModel {
    @Published var value = "" {
        willSet { self.objectWillChange.send() } // < works only if above
    }
}

Also such case is possible for consideration:

class SuperModel {
}

class Model: SuperModel, ObservableObject {
    @Published var value = ""
}


来源:https://stackoverflow.com/questions/60702699/view-refreshing-not-triggered-when-observableobject-is-inherited-in-swiftui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!