我在运行时动态地使用许多 UITextField
字段填充垂直 UIScrollView
字段。我遇到的问题是键盘会隐藏它会出现的区域中的字段,这可能包括我正在编辑的字段。
我试过了 KeyboardManagement来自苹果文档的解决方案,还尝试了 textFieldDidBeginEditing
和 textFieldDidEndEditing
上的通知,但两种情况下的问题是 keyboardWillShow
通知有时会先出现,在那种情况下,它不会让我知道正在编辑的是哪个字段。
我在一个实现 UITextFieldDelegate
协议(protocol)的类中有这段代码,这个类的每个对象都持有对这些字段之一的引用并作为它的委托(delegate)工作
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeTextfield = self.valueTextField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeTextfield = nil
}
activeTextfield
变量是对所有这些发生的 UIViewController
中变量的弱引用。在那个 View Controller 中,我有以下代码
class MyClass: UIViewController {
var activeTextfield: CustomTextField! // This is the variable I was talking about on the previous paragraph
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardWillShow(_ notification: Notification) {
if self.view.frame.origin.y == 0 {
guard let userInfo = notification.userInfo else { return }
guard let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardFrame = keyboardSize.cgRectValue
let textFieldFrame = activeTextfield!.frame // activeTextfield sometimes is nil because this notification happens before the previous code block
if textFieldFrame.origin.y + textFieldFrame.size.height > keyboardFrame.origin.y {
self.view.frame.origin.y -= keyboardFrame.height
}
}
}
@objc func keyboardWillHide(_ notification: Notification) {
if self.view.frame.origin.y != 0 {
guard let userInfo = notification.userInfo else { return }
guard let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardFrame = keyboardSize.cgRectValue
self.view.frame.origin.y += keyboardFrame.height
}
}
}
有什么方法可以强制在键盘通知之前调用 UITextField
委托(delegate)方法?
这是处理这种情况的正确方法吗?
如果没有,我该如何处理?
谢谢
最佳答案
如您的问题所述:
the problem in both cases is that the keyboardWillShow notification comes first sometimes, and in that case it doesn't let me know which field is the one being edited
根据 sequence of events在 apple 的文档中描述,textFieldShouldBeginEditing
是第一个调用的委托(delegate)方法。
所以,你可以
- 在委托(delegate)中实现
textFieldShouldBeginEditing
以设置您的事件文本字段,而不是textFieldDidBeginEditing
(确保您从 textFieldShouldBeginEditing返回 true
以允许编辑) - 使用
keyboardDidShowNotification
而不是keyboardWillShowNotification
。
这将确保您在获取键盘框架/详细信息之前标记了您的 UITextField
。
关于ios - 如何同时获取键盘的大小和选中的 UITextField 的 CGFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55869942/