I'm using .onReceive(_:perform:)
to add pattern masks in my text field text. There is an infinite loop that happens when I use array of ObservableObjects
, Binding
, State
objects or Published
properties.
Example
struct MyTextField: View {
@Binding var text: String
...
}
extension MyTextField {
func mask(_ mask: String) -> some View {
self.onReceive(Just(text)) { newValue in
// `string(withMask:)` returns another string (already formatted correctly)
text = newValue.string(withMask: mask) // Obviously when I comment this line of code, the problem stops
}
}
}
Usage
final class FormItem: ObservableObject, Identifiable {
let id = UUID()
@Published var text = ""
let mask: String
init(mask: String) {
self.mask = mask
}
}
@State var volunteerForm: [FormItem] = [
FormItem(mask: "999.999.999-99")
]
var body: some View {
VStack {
ForEach(volunteerForm.indices, id: \.self) { index in
MyTextField("", text: volunteerForm[index].$text, onCommit: onCommit)
.mask(volunteerForm[index].mask)
}
}
}
But when I use a single property just like this @State var formItem: FormItem = ...
this infinite loop doesn't happen. Also when I use an array of String
instead of array of my Class FormItem
, @State var volunteerTexts: [String] = [""]
, it doesn't happen too.
I wonder if this happen when we use a custom struct
or class
.
I've tried creating the model without ObservableObject
and Published
, just like a struct, but the infinite loop keeps happening:
struct FormItem: Identifiable {
let id = UUID()
var text = ""
let mask: String
}
VStack {
ForEach(volunteerForm.indices, id: \.self) { index in
TextField("", text: $volunteerForm[index].text, onCommit: onCommit)
.mask(volunteerForm[index].mask)
}
}
Do you have any ideia why is this infinite loop occurring?