shouldAutorotate не вызывается на контроллере представления

У меня есть простое приложение, состоящее из одного контроллера представления. Я начал с шаблона приложения Xcode 7 GM Single View, но затем удалил основную раскадровку и настроил свой контроллер представления следующим образом:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let vc = ViewController()

    window = UIWindow(frame: UIScreen.mainScreen().bounds)
    window!.rootViewController = vc
    window!.makeKeyAndVisible()

    return true
}

В моем информационном списке все ориентации указаны в разделе «Поддерживаемые ориентации интерфейса», и приложение поворачивается ко всем ориентациям на iPad.

Однако в моем простом¹ контроллере представления методы shouldAutorotate() и supportedInterfaceOrientations() никогда не вызываются. Это проблема, потому что я экспериментирую с элементом управления пользовательского интерфейса, включающим и отключающим автоматическое вращение. Что может помешать вызвать эти методы?

Пример проекта здесь (требуется Swift 2)


¹не-UINavigationController


person Zev Eisenberg    schedule 12.09.2015    source источник


Ответы (3)


Согласно этому сообщению на форуме разработчиков Apple, если у вас включена многозадачность iPad (новое в iOS 9), вы больше не можете контролировать поддерживаемые вами ориентации:

https://forums.developer.apple.com/message/13508#13508

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

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

Также обратите внимание, что автоматическое вращение на self.navigationController.view.superview.superview, вероятно, не лучший способ и может сломаться в какой-то момент в будущем. Вероятно, есть лучший способ получить правильное представление, используемое для противодействия вращению. Очевидно, что если вы не используете навигационный контроллер, вам нужно будет перейти в другое представление. YMMV.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    self.startingInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [self updateLayoutsForCurrentOrientation:toInterfaceOrientation view:self.navigationController.view.superview.superview];
}

- (void)updateLayoutsForCurrentOrientation:(UIInterfaceOrientation)toInterfaceOrientation view:(UIView *)view {
    CGAffineTransform transform = CGAffineTransformIdentity;

    if (self.startingInterfaceOrientation == UIInterfaceOrientationPortrait) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformIdentity;
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            default:
                break;
        }
    }
    view.transform = transform;
}

Большая часть этого кода была адаптирована из JTSImageViewController Джареда Синклера (опубликована с его разрешения), доступного по лицензии MIT на github здесь: https://github.com/jaredsinclair/JTSImageViewController

person Greg G    schedule 12.09.2015
comment
Спасибо. Возможно, я действительно смогу помочь вам с поворотом вашего угла. В -viewWillTransitionToSize:withTransitionCoordinator: позвоните [UIView setAnimationsEnabled:NO];, затем [coordinator animateAlongsideTransition:nil completion:..., а в завершение позвоните [UIView setAnimationsEnabled:YES]; - person Zev Eisenberg; 12.09.2015
comment
Благодарю. Мне нравится, как выглядит документация Apple ∞???? - person Duck; 12.03.2017

Чтобы отказаться от участия в режимах Slide Over и Split View, добавьте ключ UIRequiresFullScreen в файл Info.plist вашего проекта Xcode и примените логическое значение YES.

person 张云龙    schedule 29.11.2016
comment
Я часами пытался заставить автоповорот работать, и это сработало. Я должен тебе пиццу. - person Austin Berenyi; 24.07.2018

Я только что попробовал решение в этой теме: https://stackoverflow.com/a/32782517/1679627

Обратите внимание, что в info.plist есть две записи: одна для поддерживаемых ориентаций на iPhone и одна для iPad.

person Nikolay    schedule 28.01.2016