我在使用@observable时遇到了一个问题。 我正在使用它来格式化信用卡的文本字段。 我创建了一个textfield格式化程序和一个自定义textfield,使用的是我在GIST中上传的冗长代码:https://gist.github.com/amrit42087/98750b2e22b299368b07ed6e78d530a8
下面的代码用于创建UI:
import SwiftUI
struct Person: Identifiable {
var id = UUID()
var name: String
var age: Int
}
struct View1: View {
@ObservedObject var personVM = PersonViewModel()
var body: some View {
NavigationView {
HStack {
Spacer()
VStack {
CreditCardTextfield()
.offset(y: 100)
Spacer()
}
Spacer()
}
.onAppear {
self.personVM.addPerson()
}
}
}
}
struct CreditCardTextfield: View {
@ObservedObject var cardFormatter = TextFieldFormatter(limit: 19, type: .cardNumber)
@State var isFirstResponder = false
var body: some View {
CustomTextField(text: $cardFormatter.text, isFirstResponder: $isFirstResponder, placeholder: "XXXX XXXX XXXX XXXX", font: .monospacedSystemFont(ofSize: 25, weight: .bold), keyboardType: .numberPad)
.frame(height: 40)
}
}
class PersonViewModel: ObservableObject {
@Published var people: [Person] = []
func addPerson() {
people.append(Person(name: "Test", age: (0...30).randomElement() ?? 0))
}
}
问题是,如果我在onexpect()中使用这一行self.personVM.addPerson(),格式化程序就无法工作。 注释掉这一行就解决了问题。 我只需要明白这个问题背后的原因。 任何帮助都将不胜感激。
视图被复制和创建了很多--每次视图更改时,您都在构造一个新版本。 所以您不希望在视图中出现这样的代码
@ObservedObject var personVM = PersonViewModel()
这将在每次视图更改时创建一个全新的视图模型。 因此,向视图添加人员,将其添加到视图模型,然后使用空视图模型创建一个新视图。
您希望在视图外部构造它并将其传递到init中。 未来的视图值将从属性中复制它(而不是回忆那个init)。 因此,使用:
@ObservedObject var personVM: PersonViewModel
并使View1如下所示
View1(personVM: personViewModel) // personViewModel was constructed beforehand
在那里构造它也要小心--因为这一行也在一个视图结构中,并将继续构造视图模型。