I created a UIViewRepresentable
to wrap UITextField
for SwiftUI, so I can e.g. change the first responder when the enter key was tapped by the user.
This is my UIViewRepresentable (I removed the first responder code to keep it simple)
struct CustomUIKitTextField: UIViewRepresentable {
@Binding var text: String
var placeholder: String
func makeUIView(context: UIViewRepresentableContext<CustomUIKitTextField>) -> UITextField {
let textField = UITextField(frame: .zero)
textField.delegate = context.coordinator
textField.placeholder = placeholder
return textField
}
func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomUIKitTextField>) {
uiView.text = text
uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
uiView.setContentCompressionResistancePriority(.required, for: .vertical)
}
func makeCoordinator() -> CustomUIKitTextField.Coordinator {
Coordinator(parent: self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: CustomUIKitTextField
init(parent: CustomUIKitTextField) {
self.parent = parent
}
func textFieldDidChangeSelection(_ textField: UITextField) {
parent.text = textField.text ?? ""
}
}
}
The first screen of the app has a "Sign in with email" button which pushes MailView that displays a CustomUIKitTextField
and uses a @Published property of an ObservableObject
view model as the TextField's text.
struct MailView: View {
@ObservedObject var viewModel: MailSignUpViewModel
var body: some View {
VStack {
CustomUIKitTextField(placeholder: self.viewModel.placeholder,
text: self.$viewModel.mailAddress)
.padding(.top, 30)
.padding(.bottom, 10)
NavigationLink(destination: UsernameView(viewModel: UsernameSignUpViewModel())) {
Text("Next")
}
Spacer()
}
}
}
Everything works fine until I push another view like MailView, say e.g. UsernameView. It is implemented exactly in the same way, but somehow the CustomUIKitTextField
gets an updateUIView
call with an empty string once I finish typing.
There is additional weird behavior like when I wrap MailView and UsernameView in another NavigationView, everything works fine. But that is obviously not the way to fix it, since I would have multiple NavigationViews then.
It also works when using an @State property instead of a @Published property inside a view model. But I do not want to use @State since I really want to keep the model code outside the view.
Is there anybody who faced the same issue or a similar one?