Я использовал UIApplicationWillChangeStatusBarOrientationNotification
в Кобо, что, кажется, делает трюк.Это намного надежнее, потому что вы хотите соответствовать выбранной ориентации пользовательского интерфейса, а не обязательно там, где находится устройство.Другими словами, вы можете позволить Apple решить, когда вам следует переориентировать свое окно.
Вот несколько фрагментов из всплывающего диалогового кода приложения Kobo на iPad (UIAlertView на iPad выглядит немного странно, поэтому Ричард Пеннер написал лучше).После нескольких сбоев с более свежими версиями iOS и необходимости отображать эти диалоги в разных ситуациях (все вокруг ориентации IIRC), мне пришлось настроить его так, чтобы он находился прямо внутри UIWindow, что означало дублирование всей логики преобразования ориентации.
Этот код взят из UIViewController, чье представление перетаскивается прямо в текущее окно.
- (void) presentDialogWindow
{
// register for orientation change notification
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(orientationWillChange:)
name: UIApplicationWillChangeStatusBarOrientationNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(orientationDidChange:)
name: UIApplicationDidChangeStatusBarOrientationNotification
object: nil];
}
- (void) orientationWillChange: (NSNotification *) note
{
UIInterfaceOrientation current = [[UIApplication sharedApplication] statusBarOrientation];
UIInterfaceOrientation orientation = [[[note userInfo] objectForKey: UIApplicationStatusBarOrientationUserInfoKey] integerValue];
if ( [self shouldAutorotateToInterfaceOrientation: orientation] == NO )
return;
if ( current == orientation )
return;
// direction and angle
CGFloat angle = 0.0;
switch ( current )
{
case UIInterfaceOrientationPortrait:
{
switch ( orientation )
{
case UIInterfaceOrientationPortraitUpsideDown:
angle = (CGFloat)M_PI; // 180.0*M_PI/180.0 == M_PI
break;
case UIInterfaceOrientationLandscapeLeft:
angle = (CGFloat)(M_PI*-90.0)/180.0;
break;
case UIInterfaceOrientationLandscapeRight:
angle = (CGFloat)(M_PI*90.0)/180.0;
break;
default:
return;
}
break;
}
case UIInterfaceOrientationPortraitUpsideDown:
{
switch ( orientation )
{
case UIInterfaceOrientationPortrait:
angle = (CGFloat)M_PI; // 180.0*M_PI/180.0 == M_PI
break;
case UIInterfaceOrientationLandscapeLeft:
angle = (CGFloat)(M_PI*90.0)/180.0;
break;
case UIInterfaceOrientationLandscapeRight:
angle = (CGFloat)(M_PI*-90.0)/180.0;
break;
default:
return;
}
break;
}
case UIInterfaceOrientationLandscapeLeft:
{
switch ( orientation )
{
case UIInterfaceOrientationLandscapeRight:
angle = (CGFloat)M_PI; // 180.0*M_PI/180.0 == M_PI
break;
case UIInterfaceOrientationPortraitUpsideDown:
angle = (CGFloat)(M_PI*-90.0)/180.0;
break;
case UIInterfaceOrientationPortrait:
angle = (CGFloat)(M_PI*90.0)/180.0;
break;
default:
return;
}
break;
}
case UIInterfaceOrientationLandscapeRight:
{
switch ( orientation )
{
case UIInterfaceOrientationLandscapeLeft:
angle = (CGFloat)M_PI; // 180.0*M_PI/180.0 == M_PI
break;
case UIInterfaceOrientationPortrait:
angle = (CGFloat)(M_PI*-90.0)/180.0;
break;
case UIInterfaceOrientationPortraitUpsideDown:
angle = (CGFloat)(M_PI*90.0)/180.0;
break;
default:
return;
}
break;
}
}
CGAffineTransform rotation = CGAffineTransformMakeRotation( angle );
[UIView beginAnimations: @"" context: NULL];
[UIView setAnimationDuration: 0.4];
self.view.transform = CGAffineTransformConcat(self.view.transform, rotation);
[UIView commitAnimations];
}
- (void) orientationDidChange: (NSNotification *) note
{
UIInterfaceOrientation orientation = [[[note userInfo] objectForKey: UIApplicationStatusBarOrientationUserInfoKey] integerValue];
if ( [self shouldAutorotateToInterfaceOrientation: [[UIApplication sharedApplication] statusBarOrientation]] == NO )
return;
self.view.frame = [[UIScreen mainScreen] applicationFrame];
[self didRotateFromInterfaceOrientation: orientation];
}
Мы используем его, загружая этот контроллер представления, добавляя его представление в окно, затем вызывая -presentModalDialog, как:
UIView *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview: theController.view];
[theController presentDialogWindow];
Я собираюсь сделать простой подкласс UIViewController, чтобы в скором времени реализовать скромные биты, и опубликую его на моем аккаунте github.Когда я это сделаю, я отредактирую это и ссылку на него.