开发者

iPad keyboard appears in wrong orientation

I have a splitView Application that has a rootViewController and DetailsViewController When the application loads the detailsViewController pops a Modal viewController that contains a UINavigationBar.

The UINavigationBar has a search bar on it (set programatically). When focus is brought to the search bar the keyboard pops-up.

However, depending on the orientation of the device (simulator) the keyboard pops-up in the wrong orientation. The keyboard is always displayed as if the ipad is in a 'normal' orientation (i.e. at the side the home key is at)

I am returning YES in all of the shouldAutoRotate Methods:

  - (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation;

To try and find out what was happening i added some debug code to each class to log the interfaceOrientation each time the shouldAutorotate event is fired while also showing when the modal viewDidLoad method fired. I did a test for each orientation: the debug output is shown below.

The debug shows that regardless of the actual device orientation, the rootViewController and DetailsViewController interface orientations are always Portrait.

The only correct logs (where interface orientation = device orientation) are the first and last(3rd) time the modal shouldAutorotate events are fired in each test.

If I rotate the iPad after the app has launched then the keyboard appears in the correct orientation.

Can anyone shed some light on why this might be happening and how to avoid it?

[PORTRAIT]

Home Button Position: bottom

Keyboard Appears: bottom

DEBUG:

APP DELEGATE- ADD SPLITVIEWCONTROLLER

DETAIL-Interface Portrait

ROOT-Interface Portrait

ROOT-Interface Portrait

DETAIL-Interface Portrait

MODAL-Interface Portrait

MODAL DID LOAD

MODAL-ROTATE START

MODAL-ROTATE END

MODAL-Interface Portrait

[LANDSCAPE]

Home Button Position: left

Keyboard Appears: left

DEBUG:

APP DELEGATE- ADD SPLITVIEWCONTROLLER

DETAIL-Interface Portrait

ROOT-Interface Portrait

ROOT-Interface Portrait

DETAIL-Interface Portrait

MODAL-Interface LANDSCAPE

MODAL DID LOAD

MODAL-ROTATE START

MODAL-ROTATE END

MODAL-Interface Portrait

MODAL-Interface LANDSCAPE

[PORTRAIT]

Home Button Position: top

Keyboard Appears: top

DEBUG:

APP DELEGATE- ADD SPLITVIEWCONTROLLER

DETAIL-Interface Portrait

ROOT-Interface Portrait

ROOT-Interface Portrait

DETAIL-Interface Portrait

MODAL-Interface Portrait

MODAL DID LOAD

MODAL-ROTATE START

MODA开发者_开发技巧L-ROTATE END

MODAL-Interface Portrait

MODAL-Interface Portrait

[LANDSCAPE]

Home Button Position: right

Keyboard Appears: right

DEBUG:

APP DELEGATE- ADD SPLITVIEWCONTROLLER

DETAIL-Interface Portrait

ROOT-Interface Portrait

ROOT-Interface Portrait

DETAIL-Interface Portrait

MODAL-Interface LANDSCAPE

MODAL DID LOAD

MODAL-ROTATE START

MODAL-ROTATE END

MODAL-Interface Portrait

MODAL-Interface LANDSCAPE


You need to let iOS handle the rotation event before presenting the modal view controller.

Here's what's happening:

  1. The app is launched.
  2. Based on the device's orientation, a screen rotate event is queued for existing view controllers.
  3. Before the screen rotate appears, your new view controller is created with the existing orientation from the view controller.
  4. The screen rotate event is handled.
  5. Your new view controller animates into existence with the wrong orientation.

It's basically a UIKit race condition. Some of these details are speculation, but the effect is obvious.

Luckily, this is really easy to fix.

Instead of creating your new view directly, schedule it to be handled on the main queue. It'll get done after the current events are dispatched, which include the rotation event.

Current:

[self presentModalViewController:newViewController animated:YES];

Fixed:

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentModalViewController:newViewController animated:YES];
});

With this new code, you get this sequence instead:

  1. The app is launched.
  2. Based on the device's orientation, a screen rotate event is queued for existing view controllers.
  3. Before the screen rotate appears, the code to create your new view controller is queued but not executed.
  4. The screen rotate event is handled.
  5. Your new view controller is created with the correct orientation from the view controller.
  6. Your new view controller animates into existence with the right orientation.


Have you added the orientations you support into the plist?

See:

http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/CoreApplication/CoreApplication.html#//apple_ref/doc/uid/TP40009370-CH6-SW9

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜