Я наконец понял это. Ключевой недостающий компонент, который я не упомянул в исходном посте, заключается в том, что контроллер представления, который управляет ландшафтом, фактически реализован как модальное представление. (См. Руководство пользователя View Controller для получения кода о том, как это сделать). В принципе, у меня есть контроллер Portrait View. (который является основным контроллером) В viewDidLoad контроллера вертикальной развертки я подаю заявку на оповещение, которое срабатывает при изменении ориентации, например:
- (void)viewDidLoad {
[super viewDidLoad];
// SECTION to setup automatic alternate landscape view on rotation
// Uses a delegate to bring the landscape view controller up as a modal view controller
isShowingLandscapeView = NO;
// Create Landscape Controller programmatically
self.landscapeViewController = [[LandscapeViewController alloc] initWithNibName:@"LandscapeViewController" bundle:[NSBundle mainBundle]];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
// END SECTION landscape modal view controller
Тогда, когда ориентация меняется, этот метод называется:
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
// Load Landscape view
landscapeViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
В то же время я удалял строку состояния из метода viewWillAppear контроллера ландшафта:
- (void)viewWillAppear:(BOOL)animated
{
// remove status bar from top of screen
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:animated];
self.myWebView.delegate = self; // setup the delegate as the web view is shown
}
и здесь возникает проблема. Контроллер книжного представления фиксирует размеры экрана перед переходом в альбомную ориентацию в виде модального вида. Затем viewWillAppear в контроллере альбомного вида удаляет строку состояния.
Итак, решение состоит в том, чтобы переместить
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:animated];
инструкция для метода directionChanged в контроллере вертикальной ориентации, ДО перехода к модальной ориентации ландшафта.
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
// remove status bar from top of screen
// NOTE: this must be declared BEFORE presenting the Modal View!!!! If it's not, the landscape view will
// contain an ugly white bar in place of the missing status bar at the top of the view.
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// Load Landscape view
landscapeViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
Обратите внимание, что, как было упомянуто выше, если вы хотите, чтобы строка состояния отображалась при ориентации назад на Портрет, вам нужно
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:animated];
в методе viewWillDisappear в контроллере альбомной ориентации.