I have the following code:
struct Credential: Equatable {
var username = ""
var password = ""
}
enum Database {
static var credential = Credential()
}
struct UsernamePasswordInput: View {
@Binding var credential: Credential
var body: some View {
Group {
TextField("Username", text: self.$credential.username)
SecureField("password", text: self.$credential.password)
}
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
struct Login: View {
private var credential: Binding<Credential>
var body: some View {
UsernamePasswordInput(credential: self.credential)
}
init() {
self.credential = Binding<Credential>(
get: {
Database.credential
}, set: { newValue in
Database.credential = newValue
}
)
}
}
struct ContentView: View {
var body: some View {
Login()
}
}
When you run this code from Xcode 13.0 on an iOS 15 device, the message Binding<String> action tried to update multiple times per frame.
appears in the Xcode console. This happens whenever you type a character into either the TextField
or the SecureField
. The message does not appear on iOS 13 or 14 devices.
I know I can solve it by just using a @StateObject
but the above code reflects the structure of a larger project. My question is: is the Xcode message somehow indicative of a problem? Is the code above principally incorrect somehow?
CodePudding user response:
Here is a possible safe workaround - use inline separated binding for each text field:
struct UsernamePasswordInput: View {
@Binding var credential: Credential
var body: some View {
Group {
TextField("Username", text: Binding(
get: { credential.username },
set: { credential.username = $0 }
))
SecureField("password", text: Binding(
get: { credential.password },
set: { credential.password = $0 }
))
}
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
Tested with Xcode 13 / iOS 15