为什么我发布的 var 没有被我的视图更新?
Why my published var is not being updated by my view?
我正在做一个个人项目来研究 SwiftUI。一切顺利,但我发现我的应用程序存在错误。
我有下面的简单视图,它在我的 ViewModel 上保存了描述、值和一些标签。我遇到 $viewModel.value 的问题。该变量未填充视图中的值。
我假设我的 @Published var value: Double? 来自我的 ViewModel 应该在用户键入某个值时更新。问题是,它不会在任何 iPhone 11 及更高版本上更新,但它在 iPhone 8.
上完美运行
public struct AddBillView: View {
@ObservedObject private var viewModel: AddBillViewModel
@Environment(\.presentationMode) var presentationMode
public let onExpenseCreated: ((_ expense: Expense)->Void)
public var body: some View {
Text("Add Expense")
VStack {
TextField("Descrição", text: $viewModel.name)
HStack {
Text("Valor \(NumberFormatter.currency.currencySymbol)")
CurrencyTextField("Value", value: $viewModel.value)
.multilineTextAlignment(TextAlignment.leading)
}
HStack {
Text("Tags")
TextField("car pets home",
text: $viewModel.tags)
}
Picker("Type", selection: $viewModel.type) {
Text("Paid").tag("Paid")
Text("Unpaid").tag("Unpaid")
Text("Credit").tag("Credit")
}
}.navigationTitle("+ Expense")
Button("Adicionar") {
if !viewModel.hasExpense() {
return
}
onExpenseCreated(viewModel.expense())
self.presentationMode.wrappedValue.dismiss()
}
}
public init(viewModel outViewModel: AddBillViewModel,
onExpenseCreated: @escaping ((_ expense: Expense)->Void)) {
self.viewModel = outViewModel
self.onExpenseCreated = onExpenseCreated
}
}
我有一个 ViewModel:
public class AddBillViewModel: ObservableObject {
@Published var name: String = ""
@Published var type: String = "Paid"
@Published var tags: String = ""
@Published var value: Double?
init(expense: Expense?=nil) {
self.name = expense?.name ?? ""
self.type = expense?.type.rawValue ?? "Paid"
self.tags = expense?.tags?.map { String([=11=].name) }.joined(separator: " ") ?? ""
self.value = expense?.value
}
func hasExpense() -> Bool {
if self.name.isEmpty ||
self.value == nil ||
self.value?.isZero == true {
return false
}
return true
}
func expense() -> Expense {
let tags = self.tags.split(separator: " ").map { Tag(name: String([=11=])) }
return Expense(name: self.name, value: self.value ?? 0.0 ,
type: ExpenseType(rawValue: self.type)!,
id: UUID().uuidString,
tags: tags)
}
}
那我用我的观点:
AddBillView(viewModel: AddBillViewModel()) { expense in
viewModel.add(expense: expense)
viewModel.state = .idle
}
我已经 google 它并花了几个小时寻找答案,但没有运气。有人有什么想法吗?
已编辑
这是 CurrencyTextField 的代码。我正在使用这个组件:
https://github.com/youjinp/SwiftUIKit/blob/master/Sources/SwiftUIKit/views/CurrencyTextField.swift
但该组件在 iPhone 8 模拟器上运行良好,并且在我的视图中使用 @State 属性。它不仅适用于我的 ViewModel
我想通了!问题是我的 AddBillViewModel 是一个 ObservableObject 并且我用 @Published[=18 标记每个 属性 =].这导致了某种双重可观察对象。
我删除了@Published,它又开始工作了。
我正在做一个个人项目来研究 SwiftUI。一切顺利,但我发现我的应用程序存在错误。
我有下面的简单视图,它在我的 ViewModel 上保存了描述、值和一些标签。我遇到 $viewModel.value 的问题。该变量未填充视图中的值。
我假设我的 @Published var value: Double? 来自我的 ViewModel 应该在用户键入某个值时更新。问题是,它不会在任何 iPhone 11 及更高版本上更新,但它在 iPhone 8.
上完美运行public struct AddBillView: View {
@ObservedObject private var viewModel: AddBillViewModel
@Environment(\.presentationMode) var presentationMode
public let onExpenseCreated: ((_ expense: Expense)->Void)
public var body: some View {
Text("Add Expense")
VStack {
TextField("Descrição", text: $viewModel.name)
HStack {
Text("Valor \(NumberFormatter.currency.currencySymbol)")
CurrencyTextField("Value", value: $viewModel.value)
.multilineTextAlignment(TextAlignment.leading)
}
HStack {
Text("Tags")
TextField("car pets home",
text: $viewModel.tags)
}
Picker("Type", selection: $viewModel.type) {
Text("Paid").tag("Paid")
Text("Unpaid").tag("Unpaid")
Text("Credit").tag("Credit")
}
}.navigationTitle("+ Expense")
Button("Adicionar") {
if !viewModel.hasExpense() {
return
}
onExpenseCreated(viewModel.expense())
self.presentationMode.wrappedValue.dismiss()
}
}
public init(viewModel outViewModel: AddBillViewModel,
onExpenseCreated: @escaping ((_ expense: Expense)->Void)) {
self.viewModel = outViewModel
self.onExpenseCreated = onExpenseCreated
}
}
我有一个 ViewModel:
public class AddBillViewModel: ObservableObject {
@Published var name: String = ""
@Published var type: String = "Paid"
@Published var tags: String = ""
@Published var value: Double?
init(expense: Expense?=nil) {
self.name = expense?.name ?? ""
self.type = expense?.type.rawValue ?? "Paid"
self.tags = expense?.tags?.map { String([=11=].name) }.joined(separator: " ") ?? ""
self.value = expense?.value
}
func hasExpense() -> Bool {
if self.name.isEmpty ||
self.value == nil ||
self.value?.isZero == true {
return false
}
return true
}
func expense() -> Expense {
let tags = self.tags.split(separator: " ").map { Tag(name: String([=11=])) }
return Expense(name: self.name, value: self.value ?? 0.0 ,
type: ExpenseType(rawValue: self.type)!,
id: UUID().uuidString,
tags: tags)
}
}
那我用我的观点:
AddBillView(viewModel: AddBillViewModel()) { expense in
viewModel.add(expense: expense)
viewModel.state = .idle
}
我已经 google 它并花了几个小时寻找答案,但没有运气。有人有什么想法吗?
已编辑
这是 CurrencyTextField 的代码。我正在使用这个组件: https://github.com/youjinp/SwiftUIKit/blob/master/Sources/SwiftUIKit/views/CurrencyTextField.swift
但该组件在 iPhone 8 模拟器上运行良好,并且在我的视图中使用 @State 属性。它不仅适用于我的 ViewModel
我想通了!问题是我的 AddBillViewModel 是一个 ObservableObject 并且我用 @Published[=18 标记每个 属性 =].这导致了某种双重可观察对象。
我删除了@Published,它又开始工作了。