Search code examples
iphoneiosipaduikeyboardiphone-softkeyboard

iOS Keyboard Location and Orientation


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?


Solution

  • 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 !