iOS Keyboard Location and Orientation
Asked Answered
A

2

3

I'm relatively new to iOS SDK, and I'm experiencing a very bizarre issue regarding the device keyboard location and orientation for an app I'm working on. The problem is that if the keyboard is open while the user multi-tasks or the app goes into background, after the user comes back to the app, the keyboard will be be displaced (with UIKeyboardWillChangeFrameNotification being raised), but in an incorrect orientation and location.

Sometimes the keyboard shows up completely off the screen too, which is completely undesired behaviour.

My questions are:

  1. What is the position and orientation of the keyboard dependant on? How is it controlled by iOS?

  2. Is there a way to detect when the keyboard is being displayed off-screen regardless of the device type and screen size? I'm thinking it would be doable by tracking UIKeyboardWillChangeFrameNotification or UIKeyboardWillShowNotification.

  3. How would I reset/set the location and orientation of the keyboard prior to displaying it? Is this even possible?

Arawn answered 8/6, 2012 at 20:50 Comment(0)
U
1

1.) Keyboard is a UIWindow, the position is dependent on the Application's Main Window.

2.) What you could do is, upon the one of the notifications UIKeyboardWillShowNotification or UIKeyboardWillChangeFrameNotification method firing, loop through the windows subviews to locate the Keyboard. In one of my applications I needed to add a subview to the keyboard. For your case you can get the frame by doing this:

//The UIWindow that contains the keyboard view - It some situations it will be better to actually
//iterate through each window to figure out where the keyboard is, but In my applications case
//I know that the second window has the keyboard so I just reference it directly
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];

//Because we cant get access to the UIPeripheral throught the SDK we will just use UIView.
//UIPeripheral is a subclass of UIView anyways
UIView* keyboard;

    //Iterate though each view inside of the selected Window
for(int i = 0; i < [tempWindow.subviews count]; i++)
{
    //Get a reference of the current view
    keyboard = [tempWindow.subviews objectAtIndex:i];

           //Assuming this is for 4.0+, In 3.0 you would use "<UIKeyboard"
           if([[keyboard description] hasPrefix:@"<UIPeripheral"] == YES) {

                  //Keyboard is now a UIView reference to the UIPeripheral we want
                  NSLog(@"Keyboard Frame: %@",NSStringFromCGRect(keyboard.frame));

           }
}

3.) Not completely sure this is possible, but with the supplied code I gave you. keyboard is now casted to a 'UIView', which you can apply your own transforms to.

This might not be the most elegant solution, but it works well for my case.

Hope this Helps !

Uralic answered 9/6, 2012 at 2:9 Comment(2)
This is pretty neat solution to finding the keyboard location. But for some reason, it doesn't always seem to be able to find the keyboard. I've made it iterate through all the UIWindows in my app, and sometimes I get nothing, even though the keyboard is up.Arawn
Also, regarding your answer to question 1: If keyboard position is dependant only on the app's main window, then under what condition could it pop up outside the main window?Arawn
O
5

From the documentation:

Use the keys described in “Keyboard Notification User Info Keys” to get the location and size of the keyboard from the userInfo dictionary.

Keys used to get values from the user information dictionary of keyboard notifications:

NSString * const UIKeyboardFrameBeginUserInfoKey;
NSString * const UIKeyboardFrameEndUserInfoKey;
NSString * const UIKeyboardAnimationDurationUserInfoKey;
NSString * const UIKeyboardAnimationCurveUserInfoKey;
Om answered 12/10, 2012 at 7:47 Comment(0)
U
1

1.) Keyboard is a UIWindow, the position is dependent on the Application's Main Window.

2.) What you could do is, upon the one of the notifications UIKeyboardWillShowNotification or UIKeyboardWillChangeFrameNotification method firing, loop through the windows subviews to locate the Keyboard. In one of my applications I needed to add a subview to the keyboard. For your case you can get the frame by doing this:

//The UIWindow that contains the keyboard view - It some situations it will be better to actually
//iterate through each window to figure out where the keyboard is, but In my applications case
//I know that the second window has the keyboard so I just reference it directly
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];

//Because we cant get access to the UIPeripheral throught the SDK we will just use UIView.
//UIPeripheral is a subclass of UIView anyways
UIView* keyboard;

    //Iterate though each view inside of the selected Window
for(int i = 0; i < [tempWindow.subviews count]; i++)
{
    //Get a reference of the current view
    keyboard = [tempWindow.subviews objectAtIndex:i];

           //Assuming this is for 4.0+, In 3.0 you would use "<UIKeyboard"
           if([[keyboard description] hasPrefix:@"<UIPeripheral"] == YES) {

                  //Keyboard is now a UIView reference to the UIPeripheral we want
                  NSLog(@"Keyboard Frame: %@",NSStringFromCGRect(keyboard.frame));

           }
}

3.) Not completely sure this is possible, but with the supplied code I gave you. keyboard is now casted to a 'UIView', which you can apply your own transforms to.

This might not be the most elegant solution, but it works well for my case.

Hope this Helps !

Uralic answered 9/6, 2012 at 2:9 Comment(2)
This is pretty neat solution to finding the keyboard location. But for some reason, it doesn't always seem to be able to find the keyboard. I've made it iterate through all the UIWindows in my app, and sometimes I get nothing, even though the keyboard is up.Arawn
Also, regarding your answer to question 1: If keyboard position is dependant only on the app's main window, then under what condition could it pop up outside the main window?Arawn

© 2022 - 2024 — McMap. All rights reserved.