我有一个SwiftUI UIViewControllerRepresentable,它已嵌入到ScrollView中(见下文)
import SwiftUI
struct ContactView: View {
@State private var text = ""
var body: some View {
ScrollView{
TextFieldView(text: $text, dismissKeyboardCallback: nil)
}
}
}
当我点击TextField时,什么也没有发生。如果将父ScrollView替换为VStack,则TextFieldRepresentable可以照常接收焦点(出现软键盘,并且可以输入数据)。这是一个错误,还是我做错了什么?如果对UIViewControllerRepresentable有所帮助,则包括在下面:
import SwiftUI
struct TextFieldView: View {
var text: Binding<String>
var onDismissKeyboard: (() -> Void)?
var body: some View {
TextFieldRepresentable(text: text, dismissKeyboardCallback: self.onDismissKeyboard)
.frame(height: 32, alignment: .leading)
}
}
struct TextFieldRepresentable: UIViewControllerRepresentable {
let dismissKeyboardCallback: (() -> Void)?
let viewController: TextFieldViewController
init (text: Binding<String>, dismissKeyboardCallback: (() -> Void)?) {
self.dismissKeyboardCallback = dismissKeyboardCallback
self.viewController = TextFieldViewController(text: text, onDismiss: dismissKeyboardCallback)
}
func makeUIViewController(context: Context) -> UIViewController {
return viewController
}
func updateUIViewController(_ viewController: UIViewController, context: Context) {}
}
还有TextFieldViewController本身:
class TextFieldViewController: UIViewController, UITextFieldDelegate {
let text: Binding<String>?
let onDismiss: (() -> Void)?
init (text: Binding<String>, onDismiss: (() -> Void)?) {
self.text = text
self.onDismiss = onDismiss
super.init( nibName: "TextField", bundle: Bundle.main)
}
required init?(coder: NSCoder) {
self.text = nil
self.onDismiss = nil
super.init(coder: coder)
}
fileprivate func getTextField() -> UITextField? {
return view.subviews.first as? UITextField
}
override func viewDidLoad() {
let textField = self.getTextField()
textField?.delegate = self
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
toolbar.barStyle = UIBarStyle.default
toolbar.items = [UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(self.onSet))]
textField?.inputAccessoryView = toolbar
}
@objc private func onSet() {
let textField = self.getTextField()
textField?.resignFirstResponder()
self.text?.wrappedValue = textField?.text ?? ""
self.onDismiss?()
}
}