View aligned to top of keyboard appears in wrong place in iOS 9 Shortcut Bar only mode

心不动则不痛 提交于 2019-11-30 22:06:57

The problem is that most code out there (including Apple's) ignores the fact that UIKeyboardFrameEndUserInfoKey is a CGRect and not a 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];
}

Here you see that only the keyboard height (kbSize.height) is being used. The origin of the rect is important, and should not be ignored.

When the keyboard is visible, this is the rect that is reported:

When the keyboard is in Shortcut Bar only mode, this is the rect:

Notice how the majority of the keyboard is offscreen, yet it is still the same height.

To get the correct behavior, use CGRectIntersection with the view's bounds and the keyboard frame within that view:

// ✅ 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

For this same reason, UIKeyboardFrameEndUserInfoKey should be used as opposed to UIKeyboardFrameBeginUserInfoKey.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!