【发布时间】:2020-01-30 16:42:19
【问题描述】:
我为 SwiftUI 创建了一个 UIViewRepresentable 来包装 UITextField,所以我可以例如当用户点击回车键时更改第一响应者。
这是我的 UIViewRepresentable(为了简单起见,我删除了第一响应者代码)
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 ?? ""
}
}
}
应用程序的第一个屏幕有一个“使用电子邮件登录”按钮,该按钮会推送显示 CustomUIKitTextField 的 MailView,并使用 ObservableObject 视图模型的 @Published 属性作为 TextField 的文本。
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()
}
}
}
在我推送另一个视图(例如 MailView)之前,一切正常,例如用户名查看。它以完全相同的方式实现,但不知何故,一旦我完成输入,CustomUIKitTextField 就会得到一个带有空字符串的 updateUIView 调用。
还有一些奇怪的行为,比如当我将 MailView 和 UsernameView 包装在另一个 NavigationView 中时,一切正常。但这显然不是解决问题的方法,因为那时我会有多个 NavigationView。
当在视图模型中使用 @State 属性而不是 @Published 属性时,它也可以工作。但我不想使用@State,因为我真的想将模型代码保留在视图之外。
有没有人遇到过同样的问题或类似的问题?
【问题讨论】:
标签: ios swift swiftui uiviewrepresentable