提问者:小点点

@可观察到不完全按要求工作


我在使用@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(),格式化程序就无法工作。 注释掉这一行就解决了问题。 我只需要明白这个问题背后的原因。 任何帮助都将不胜感激。


共1个答案

匿名用户

视图被复制和创建了很多--每次视图更改时,您都在构造一个新版本。 所以您不希望在视图中出现这样的代码

@ObservedObject var personVM = PersonViewModel()

这将在每次视图更改时创建一个全新的视图模型。 因此,向视图添加人员,将其添加到视图模型,然后使用空视图模型创建一个新视图。

您希望在视图外部构造它并将其传递到init中。 未来的视图值将从属性中复制它(而不是回忆那个init)。 因此,使用:

@ObservedObject var personVM: PersonViewModel

并使View1如下所示

View1(personVM: personViewModel) // personViewModel was constructed beforehand

在那里构造它也要小心--因为这一行也在一个视图结构中,并将继续构造视图模型。