问题在于大多数代码(including Apple 的)忽略了 UIKeyboardFrameEndUserInfoKey 是 CGRect 而不是 CGSize 的事实.
// ❌ Bad code, do not use
- (void)keyboardWasShown:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = activeField.superview.frame;
bkgndRect.size.height += kbSize.height;
[activeField.superview setFrame:bkgndRect];
[scrollView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}
在这里您看到只有键盘高度 (kbSize.height) 正在使用。 rect 的来源很重要,不容忽视。
当键盘可见时,这是报告的矩形:
当键盘处于仅快捷栏模式时,这是矩形:
注意键盘的大部分是如何在屏幕外的,但它仍然是相同的高度。
要获得正确的行为,请将CGRectIntersection 与视图的边界和该视图内的键盘框架一起使用:
// ✅ Good code, use
CGRect keyboardScreenEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardViewEndFrame = [self.view convertRect:keyboardScreenEndFrame fromView:self.view.window];
CGRect keyboardFrame = CGRectIntersection(self.view.bounds, keyboardViewEndFrame);
CGFloat keyboardHeight = keyboardFrame.size.height; // = 55
出于同样的原因,应该使用UIKeyboardFrameEndUserInfoKey 而不是UIKeyboardFrameBeginUserInfoKey。