SwiftUI 视图不会为具有子类的已发布对象更新
Posted
技术标签:
【中文标题】SwiftUI 视图不会为具有子类的已发布对象更新【英文标题】:SwiftUI view does not update for Published objects with subclasses 【发布时间】:2022-01-05 01:20:51 【问题描述】:因为我的实际代码有点复杂,这里有一个简化的类结构,我可以用它重现相同的意外行为。
这是我的子类的基础数据对象:
class People: Identifiable
var name: String
required init(name: String)
self.name = name
class Men: People
然后我使用另一个类,它也充当超类,但也使用People
的泛型类型。
class SuperMankind<PlayerType: People>
var people: [PlayerType] = []
class Mankind: SuperMankind<Men>
现在我想在我的 ViewModel 中使用这个 Mankind
子类,它是一个 ObservableObject。
class ViewModel: ObservableObject
@Published var mankind: Mankind
init(_ m: Mankind)
mankind = m
struct TestView: View
@StateObject var viewModel = ViewModel(Mankind())
var body: some View
VStack
Button("Add")
viewModel.mankind.people.append(Men(name: Int.random(in: 0...1000).description))
List
ForEach(viewModel.mankind.people)
Text($0.name)
但是如果我单击添加按钮,我的视图不会更新,我不知道为什么。我发现如果我将以下代码添加到我的按钮操作中,视图就会更新。但在我看来,这个手动调用不应该是必要的,所以我认为我做错了什么。
viewModel.objectWillChange.send()
【问题讨论】:
【参考方案1】:@SwiftSharp 感谢您的回答和associatedType
我没想到这一点。但是 @Published
字段需要是结构体是不正确的考虑这个解决方案,我现在会选择这个解决方案,因为我不想让我的所有函数都发生变异。
class People: Identifiable
var name: String
required init(name: String)
self.name = name
class Men: People
class SuperMankind<PlayerType: People>: ObservableObject
@Published var people: [PlayerType] = []
class Mankind: SuperMankind<Men>
struct TestView: View
@StateObject var viewModel = Mankind()
var body: some View
VStack
Button("Add")
viewModel.people.append(Men(name: Int.random(in: 0...1000).description))
List
ForEach(viewModel.people)
Text($0.name)
我的问题是 ViewModel
类不是必需的,而且我的包含人员数组的超类不是 ObervableObject。
编辑在这里完成:
这也将解决我的初始代码问题,使用 ViewModel 类,但不是子类化 ObservableObject,我将从 Mankind
子类化,它已经通过继承 SuperMankind 符合 ObservableObject:
class ViewModel: Mankind
【讨论】:
【参考方案2】:ObservableObject
requires that its fields are structs, not classes.
我稍微修改了你的代码,它起作用了:
protocol SuperMankind
associatedtype PlayerType
var people: [PlayerType] get set
struct Mankind: SuperMankind
var people: [Men] = []
Screenshot here
您的解决方案(因为我无法发表评论):
Array<Men>
是一个结构,尽管数组包含类引用。这就是为什么您的代码现在可以正常工作的原因,就像之前您在 ObservableObject
中直接持有对类的引用一样(因此没有更新视图)。
【讨论】:
特别是因为您帮助我了解了问题的根本原因。 只是出于兴趣,您宁愿选择没有 viewModel 的我的解决方案,还是将我编辑的方法与 viewModel 类一起使用? @AlexB 我会说你没有 ViewModel 类的方法会是两者中更好的方法,尽管我不会尝试使用类,除非我绝对需要,尤其是在使用 SwiftUI 时。以上是关于SwiftUI 视图不会为具有子类的已发布对象更新的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 不会将状态更新为 @ObservedObject cameraViewModel 对象
SwiftUI:具有计时器样式的文本在提供的日期更改后不会更新
SwiftUI:如何使用位置管理器类的已发布属性更新一个类(ObservableObject)的已发布属性?
SwiftUI:如果 @ObservedObject 是 UIViewController 的子类,则不会重新加载视图内容。这是一个错误还是我错过了啥?