Как реализовать вращение UIViewController в ответ на изменения ориентации?

Мое приложение имеет приблизительно 10 различных UIViewControllers, только один из которых я хочу переключиться на альбомный режим, если устройство повернуто. (Все остальные, я хочу сохранить в портрете.)

Для реализации вращения на том одном представлении я должен был реализовать 'shouldAutorotate' метод его контроллера и возвратить ДА. Так как к этому представлению получают доступ через контроллер навигации, я также должен был создать подкласс UINavigationController, который реализует 'shouldAutorotate', и возвратите ДА.

Это решение работы, но слишком хорошо. Я нахожу, что все UIViewControllers, которые я продвигаю на свой подкласс UINavigationController, отвечают на вращение, даже если я реализую 'shouldAutorotate' и возвращаюсь НЕТ. (Помните: Я только хочу, чтобы один конкретный UIViewController ответил на вращение, не всех в стопке контроллера навигации.)

Так, мой вопрос: как я лучше всего делаю это? Все решения, которые я могу предложить, кажутся 2) 1) громоздкий и 2) хуже, кажись, не работать.

Большое спасибо.

7
задан Greg Maletic 14 May 2010 в 23:37
поделиться

2 ответа

Я видел примеры того, как вы это делаете, но не мог заставить его работать должным образом. Я нашел лучший способ сделать это на примерах Apple. В основном вы реализуете PresentModalViewController и создаете другое представление. UIKit выполняет базовую анимацию вращения и исчезает между видами. Вы должны реализовать повернутое представление как класс делегата, чтобы он мог вернуться к своему вызывающему классу, чтобы отклонить его и обновить ориентацию.

- (void)orientationChanged:(NSNotification *)notification
{
    // We must add a delay here, otherwise we'll swap in the new view
    // too quickly and we'll get an animation glitch
    NSLog(@"orientationChanged");
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}

А затем для отображения экрана в альбомной ориентации:

- (void)updateLandscapeView
{
PortraitView *portraitView = [[PortraitView alloc] init];
portraitView.delegate = self;
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
    [self presentModalViewController: portraitView animated:YES];
    isShowingLandscapeView = YES;
    }
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
    [self dismissModalViewControllerAnimated:YES];
    isShowingLandscapeView = NO;
    }
[portraitView release];
}
0
ответ дан 7 December 2019 в 14:29
поделиться

Я делаю это, имея корневой контроллер представления (это может быть UITabBarController), и в его методе viewDidLoad я подписываюсь на события вращения:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didRotate:)
                                                      name:@"UIDeviceOrientationDidChangeNotification" 
                                                      object:nil];

Затем в методе didRotate: я смотрю, какой Контроллер представления виден, когда произошло вращение, и в какой ориентации находится телефон:

- (void) didRotate:(NSNotification *)notification { 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

/*
    DEVICE JUST ROTATED TO PORTRAIT MODE

 orientation == UIDeviceOrientationFaceUp ||
 orientation == UIDeviceOrientationFaceDown

 */
if(orientation == UIDeviceOrientationPortrait) {





/*
    DEVICE JUST ROTATED TO LANDSCAPE MODE
 */
}else if(orientation == UIInterfaceOrientationLandscapeLeft ||
        orientation == UIInterfaceOrientationLandscapeRight) {






}

}

Внутри этого didRotate: вы можете посмотреть, какой является видимым viewController, и делать оттуда то, что вы хотите.

Я представляю контроллер модального представления в ландшафтном режиме, когда виден конкретный контроллер представления, а телефон повернут в альбомную ориентацию. Если виден какой-либо другой контроллер представления, я игнорирую событие.

Я заставляю мой модальный контроллер представления отображать альбомный режим в его методе viewWillAppear - я могу передать этот код кому угодно, если он этого захочет.

Надеюсь, это поможет.

Дэйв

1
ответ дан 7 December 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: