在SwiftUI中继承ObservableObject时不触发视图刷新

时间:2020-03-16 08:41:03

标签: ios swift swiftui combine

ContentView2视图在model.value更改时不会刷新,如果Model直接符合ObservableObject而不是继承SuperModel,那么它就可以正常工作

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

    }
}

3 个答案:

答案 0 :(得分:6)

这是您的示例的有效变体。请注意,要能够正常工作,不仅需要链接发布者,而且至少需要链接一个Publisher属性。在某种程度上,它可能会有所帮助。

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

将代码更改为

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

    }

您可以看到如何同时使用超级模型

enter image description here

答案 1 :(得分:1)

使用ObjectWillChange解决指定的问题。

这是工作代码:

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

答案 2 :(得分:-1)

这看起来确实很严重。

class SuperModel: ObservableObject {
}

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

我看到value被更改并按预期保留了新的,但是DynamicProperty功能不起作用

以下变体对我有效(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
    }
}

这种情况也可以考虑:

class SuperModel {
}

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