NebulaFox
NebulaFox

Reputation: 8303

UIKeyboard's Frame is 20 pixels off

I need someone to explain this to me as it is not making any sense.

When getting the UIKeyboards frame from the userInfo using UIKeyboardFrameEndUserInfoKey and doing the math so that a view would appear to be stacked on top of the keyboard, I need to make a difference of 20 pixels.

The math:

CGRect frame = view.frame;
CGPoint origin = frame.origin;
origin.x = kbFrame.origin.x;
origin.y = kbFrame.origin.y - view.frame.size.height - 20;
frame.origin = origin;
view.frame = frame;

I thought it must be the status bar, but here's the kicker, I'm developing on a retina display and so the status bar is 40 pixels in height not 20.

I then added a the conversion from view to view

CGRect kbFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

UIWindow * window = [UIApplication sharedApplication].windows[0];

kbFrame = [self.view convertRect:kbFrame fromView:window];

and that seems to fixed of it; that is I can remove the 20 pixels difference.

What really throws me is when using UIKeyboardFrameBeginUserInfoKey, the keyboard's frame is at the bottom of the screen, which is correct, but the end frame causes me to encode a 20 pixel difference. When I add the conversion code in, it puts the keyboard 20 pixels up and so gets rid of the difference. What the hell is going on?

Upvotes: 0

Views: 295

Answers (1)

Vincent Bernier
Vincent Bernier

Reputation: 8664

The thing you are describing is the natural and wanted behaviour.
The thing is that the keyboard coordinate are in the Window Coordinate system.
Your view is probably not in Window Coordinate system. So you always need to do a conversion between coordinate system to be able to use it correctly.

What really throws me is when using UIKeyboardFrameBeginUserInfoKey, the keyboard's frame is at the bottom of the screen, which is correct,

I would disagree, you are probably 20 points lower than what you think you are (if you are setting it in your View coordinate system), but since that is off the screen you don't notice the offset.

Every View have it's own coordinate system that is inside it's bounds. And the frame of a view is expressed in it's parent coordinate system. That can also lead to some confusion if we don't understand the why and necessity of this difference.

I hope this will help you.

NOTE on Retina Display and Measurement :
On iOS you never deal with Pixel in your code (only when preparing your assets) you always deal with Point. So the Status bar is always 20 points, on Retina or not.

Upvotes: 1

Related Questions