问题描述
我正在尝试使用@ObservableObject viewmodel,它在我的视图结构中声明为@Observedobject。问题是,当viewmodel更改其“域”属性@Published var时,UI不会更新。另外,我更改了init(){}内的getDomains()函数内的域。看起来好像被叫了两次,为什么会这样呢?这是我的viewmodel代码:
Content View
该视图的代码: 进口基金会 导入SwiftUI 导入合并
sizeforItemAt:
有人可以帮我吗?谢谢。
解决方法
引用here的答案
如果可以更改数据,则需要一个动态的ForEach循环(带有显式id参数):
ForEach(viewModel.domains.indices,id: \.self) { index in // <=
// ...
}
在某些情况下,当您尝试修改ForEach循环中使用的数组时,Xcode会警告您:
ForEach(:content :)仅应用于常量数据。而是使数据符合Identifiable或使用ForEach(:id:content :)并提供明确的ID!
经过测试的代码
struct DomainsOfInterestView: View {
@ObservedObject var viewModel: DomainsViewModel = DomainsViewModel()
@State var isActive = true
var body: some View {
VStack(alignment: .center) {
HStack {
Text("Choose domains of interest for your profile")
.font(.headline)
Spacer()
}.padding(.bottom,16)
ForEach(viewModel.domains.indices,id: \.self) { index in // <=
Text(String(index))
}
Button(action: {
}) {
Text("Save")
}.padding(.top,30)
.padding([.leading,.trailing],30)
Spacer()
}.padding([.leading,12)
.navigationBarTitle("Domains of interest")
}
}
class DomainsViewModel: ObservableObject {
@Published var domains: [Int] = [Int]()
init() {
self.getDomains { (response) in
print(response)
}
}
func getDomains(completion: @escaping (Bool) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.domains = [1,2,3,4,5]
completion(true)
}
}
}
在iOS 14 beta 6上使用Xcode 12 beta 6进行了测试
, 在每次更新视图模型时都会重新创建 DomainsOfInterestView
。然后,您每次都使用新的DomainsViewModel
实例初始化视图模型属性。新的视图模型会将domains
属性设置为[InterestDomain]()
,并且将再次调用self.getDomains
。
首先,最好将ViewModel插入启动器中的DomainsOfInterestView
中,如@youjin在上一篇文章的评论中所写。此外,如果最低部署目标允许,则可以使用@StateObject
代替@ObservedObject
。在这种情况下,不会在每次更新视图时重置viewModel
属性。