我在InputAccessoryView上遇到一个奇怪的行为,我正在使用我InputAccessoryView
注册了KeyboardWillShow
和KeyboardWillHide
通知的聊天屏幕上工作。当我的聊天屏幕出现时,它会自动调用一次KeyboardWillShowMethod
,此后它会自动隐藏而不会调用KeyboardWillHide
通知。在加载聊天之后,当我单击文本框键入文本时,它会调用KeyboardWillShow
,这很好。但是,当我尝试隐藏keybaord时,它首先调用两个方法,它将调用KeyboardWillHide
,然后将调用KeyboardWillShow
,这很奇怪。
这是我的聊天屏幕Image,当键盘被隐藏时。 这是显示键盘Image
的时间我正在以编程方式inputAccessoryView使用此InputAccessoryView
代码
这是我注册键盘通知的方式。
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
插入值,因为我没有得到键盘高度的问题。从inputAccessoryView的高度开始,滑道的高度始终为50。
答案 0 :(得分:0)
这是我为@Amit找到Thanx的解决方案。执行此操作后,我不再使用UIKeyboardFrameBeginUserInfoKey
,而是使用UIKeyboardFrameEndUserInfoKey
,我可以使用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
})
}
}
答案 1 :(得分:0)
键盘输入附件视图后,两次观察到keyboardDidHideNotification
:
如果您的实现依赖于选择器仅被调用一次,则可以执行以下解决方法之一:
选项A:检查键盘框架:
@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
}
}
选项B:使用GDC的油门反应:
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)
}