【发布时间】:2020-12-25 09:14:04
【问题描述】:
我正在尝试使用在我的视图结构中声明为@ObservedObject 的@ObservableObject viewModel。问题是,当 viewModel 更改它的“域”属性 @Published var 时,UI 不会更新。此外,我更改了在 init() {} 中调用的 getDomains() 函数中的域。看起来它被调用了两次,为什么会这样?这是我的 viewModel 代码:
import Combine
class DomainsViewModel: ObservableObject {
@Published var domains: [InterestDomain] = [InterestDomain]()
init() {
self.getDomains { (response) in
print(response)
}
}
func getDomains(completion: @escaping (Bool) -> Void) {
NetworkEngine.shared.appNetwork.getInterestDomains { result in
self.domains.removeAll()
switch result {
case .success(let domainsOfInterest):
if let domainsList = domainsOfInterest {
self.domains = domainsList
}
completion(true)
case .failure(_):
completion(false)
}
}
}
}
视图代码: 进口基金会 导入 SwiftUI 导入合并
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) { index in
DomainOfInterestElement(isActive: self.$isActive, domain: self.viewModel.domains[index].name)
}
OrangeButton(action: {
}) {
Text("Save")
}.padding(.top, 30)
.padding([.leading, .trailing], 30)
Spacer()
}.padding([.leading, .trailing], 12)
.navigationBarTitle("Domains of interest")
}
}
struct DomainsOfInterestView_Previews: PreviewProvider {
static var previews: some View {
DomainsOfInterestView()
}
}
struct DomainOfInterestElement: View {
@Binding var isActive: Bool
var domain: String
var body: some View {
Button(action: {
self.isActive.toggle()
}) {
VStack {
Divider().padding(.bottom, 12)
HStack {
checkBoxView()
.frame(width: 36, height: 36)
textView().font(.custom("SFProDisplay-Regular", size: 16))
Spacer()
}
}
}
}
func checkBoxView() -> Image {
switch isActive {
case true:
return Image(uiImage: #imageLiteral(resourceName: "check-box-active-2-1")).renderingMode(.original)
case false:
return Image(uiImage: #imageLiteral(resourceName: "check-box-active-1")).renderingMode(.original)
}
}
func textView() -> Text {
switch isActive {
case true:
return Text(domain)
.foregroundColor(.black)
case false:
return Text(domain)
.foregroundColor(Color.orGrayColor)
}
}
}
谁能帮帮我?谢谢。
【问题讨论】:
-
除了下面的答案,您可能需要小心处理多个线程。我看不到 getInterestDomains 的代码,但它可能在后台线程中回调。然后在后台线程中更改已发布的 var 可能会导致发生未定义的事情(例如视图未按应有的方式更新)。您可能需要分派回主队列。这是在视图中不初始化 viewModel 的补充,除非您使用 @StateObject。
标签: swift swiftui reactive-programming combine