Swift “输入附件视图”在键盘隐藏和显示事件中意外行为
我在使用InputAccessoryView时遇到了一个奇怪的行为,我正在聊天屏幕上使用InputAccessoryView,我在其中注册了KeyboardWillShow和KeyboardWillHide通知。当我的聊天屏幕出现时,它会自动调用KeyboardWillShowMethod一次,然后自动隐藏,而不调用KeyboardWillHide通知。加载聊天后,当我点击文本框键入它调用的文本时,Keyboard将显示这一点。但当我试图隐藏keybaord时,它会调用两个方法,首先它会调用KeyboardWillHide,然后它会调用KeyboardWillShow,这很奇怪 这是我隐藏键盘时的聊天屏幕。 此时显示键盘 我以编程的方式使用这个InputAccessoryView代码 这就是我注册键盘通知的方式Swift “输入附件视图”在键盘隐藏和显示事件中意外行为,swift,keyboard-events,inputaccessoryview,Swift,Keyboard Events,Inputaccessoryview,我在使用InputAccessoryView时遇到了一个奇怪的行为,我正在聊天屏幕上使用InputAccessoryView,我在其中注册了KeyboardWillShow和KeyboardWillHide通知。当我的聊天屏幕出现时,它会自动调用KeyboardWillShowMethod一次,然后自动隐藏,而不调用KeyboardWillHide通知。加载聊天后,当我点击文本框键入它调用的文本时,Keyboard将显示这一点。但当我试图隐藏keybaord时,它会调用两个方法,首先它会调用Ke
func handleKeyBoard(){
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
var contentInset = self.collectionView?.contentInset
contentInset?.bottom = keyboardSize.maxY
self.collectionView?.contentInset = contentInset!
self.collectionView?.scrollIndicatorInsets = contentInset!
// collectionViewBottomAnchor?.constant = keyboardSize.height + 50
// print ("input height \(inputAccessoryView?.frame.maxY) ")
// print("keyboard height \(keyboardSize.height)")
// print("keyboard Y \(keyboardSize.maxY)")
// print("keyboard Y \(keyboardSize.minY)")
//print("keyboard Y \(inputAccessoryView.framemaxY)")
if self.messages.count > 0{
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: { (completed:Bool) in
let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
})
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
print("keyboard hide")
self.collectionView?.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)
self.collectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: { (completed:Bool) in
})
}
}
在选择器中,我试图根据键盘的Y索引更改我的CollectionView插图,因为我无法获得键盘的高度,这也是一个问题。kyeboard的高度始终是输入AccessoryView高度的50。这是我找到的解决方案,它可以解决@Amit。我没有使用UIKeyboardFrameBeginUserInfo键,而是使用了UIKeyboardFrameEndUserInfo键。完成此操作后,我能够在KeyboardWillAppear方法中获得准确的键盘高度。现在仍然存在的问题是,KeyboardWillShow方法在KeyboardWillHide之后被调用,但当时KeyboardWillShow的键盘高度为50。 这意味着当我试图隐藏键盘时,它会调用KeyboardWillHide,这很好,之后它会自动调用KeyboardWillShow,但键盘的高度仍然是50,所以我在那个里设置了条件 现在,以下方法只有在高度超过50时才会生效
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if keyboardSize.height > 50{
var contentInset = self.collectionView?.contentInset
contentInset?.bottom = keyboardSize.height + 50
self.collectionView?.contentInset = contentInset!
self.collectionView?.scrollIndicatorInsets = contentInset!
if self.messages.count > 0{
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: { (completed:Bool) in
let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
})
}
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
self.collectionView?.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)
self.collectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 52, right: 0)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: { (completed:Bool) in
})
}
}
当键盘具有“输入附件”视图时,将观察键盘显示两次:
当键盘被隐藏时。
当input accessroy视图处于隐藏状态时,请注意,键盘关闭后,input accessroy视图将在一段时间内可见。
如果您的实现依赖于只调用一次选择器,则可以执行以下解决方法之一:
选项A:检查键盘框架:
选项B:使用GDC的油门反应:
显示您的选择器代码。@RakeshaShastri我已使用选择器方法更新了问题。请尝试使用UIKeyboardFrameBeginUserInfoKey代替UIKeyboardFrameBeginUserInfoKey。同时检查此项:如果对您的场景有帮助。嘿@Amit谢谢。这很有帮助。
@objc
private func keyboardDidHide(_ notification: Notification) {
guard let keyboardRect = notification.keyboardRect, keyboardRect.origin.y == view.frame.maxY else {
return
}
// Do whatever you need...
}
extension Notification {
var keyboardRect: CGRect? {
guard let keyboardSize = userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
return nil
}
return keyboardSize.cgRectValue
}
}
private var pendingKeyboardDidHideRequestWorkItem: DispatchWorkItem?
private func keyboardDidHide(_ notification: Notification) {
pendingKeyboardDidHideRequestWorkItem?.cancel()
let keyboardDidHideRequestWorkItem = DispatchWorkItem { [weak self] in
// Do whatever you need...
}
pendingKeyboardDidHideRequestWorkItem = keyboardDidHideRequestWorkItem
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500), execute: keyboardDidHideRequestWorkItem)
}