Технические вопросы и ответы QA1890

Препятствование тому, чтобы вращалось представление

Q: Мой контроллер представления поддерживает авторотацию, но я должен заблокировать ориентацию определенного подпредставления. Как я могу препятствовать тому, чтобы вращалось представление?

A: Авторотация реализована путем применения вращения, преобразовывают к окну приложения, когда система решает, что должен вращаться интерфейс. Окно тогда приводит свои границы в соответствие с новой ориентацией и распространяет это изменение вниз через иерархию контроллера представления через вызовы к каждому контроллеру представления и контроллеру представления -viewWillTransitionToSize:withTransitionCoordinator: метод. Вызовам этого метода предоставлены координатора перехода объект, содержащий дельту текущего преобразования окна и нового преобразования, которое может быть получено путем отправки a -targetTransform обменивайтесь сообщениями координатору перехода. Ваш контроллер представления или контроллер представления могут получить надлежащее обратное преобразование и применить его к целевому представлению. Это аннулирует эффект окна, преобразовывают на том определенном представлении, и дает появление, что представление осталось фиксированным в своей текущей ориентации, поскольку остальная часть интерфейса обычно вращается.

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

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
 
    self.notRotatingView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
}
 
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
 
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        CGAffineTransform deltaTransform = coordinator.targetTransform;
        CGFloat deltaAngle = atan2f(deltaTransform.b, deltaTransform.a);
 
        CGFloat currentRotation = [[self.notRotatingView.layer valueForKeyPath:@"transform.rotation.z"] floatValue];
        // Adding a small value to the rotation angle forces the animation to occur in a the desired direction, preventing an issue where the view would appear to rotate 2PI radians during a rotation from LandscapeRight -> LandscapeLeft.
        currentRotation += -1 * deltaAngle + 0.0001;
        [self.notRotatingView.layer setValue:@(currentRotation) forKeyPath:@"transform.rotation.z"];
 
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        // Integralize the transform to undo the extra 0.0001 added to the rotation angle.
        CGAffineTransform currentTransform = self.notRotatingView.transform;
        currentTransform.a = round(currentTransform.a);
        currentTransform.b = round(currentTransform.b);
        currentTransform.c = round(currentTransform.c);
        currentTransform.d = round(currentTransform.d);
        self.notRotatingView.transform = currentTransform;
    }];
}

Соображения

Вышеупомянутый метод должен только быть применен к представлениям, которые Ваш контроллер представления непосредственно ответственен за расположение (т.е. потомков Вашего представления контроллера представления). Контроллер представления никогда не должен изменять преобразование или другие геометрические свойства его собственного представления, ими управляют родительский контроллер представления или контроллер представления. Если необходимо препятствовать тому, чтобы контроллер представления вращался, посмотрите Управление, Какие Интерфейсные Ориентации Поддерживаются в Руководстве по программированию Контроллера Представления для iOS.

Авторасположение

Изменение преобразования представления, выбравшего в Авторасположение, не рекомендуется. При использовании Авторасположения фактор представление, к которому преобразование будет применено в разделение xib файл с отключенным Авторасположением. Тогда во время выполнения, загрузите xib файл и программно добавьте представление к иерархии представления.

Перечисление 2  , Загружающееся notRotatingView от xib файла.

// Connected to the root view in the xib.
@property (nonatomic, strong) IBOutlet UIView *notRotatingView;
 
- (void)viewDidLoad
{
    [super viewDidLoad];
 
    // Load the notRotatingView from a xib, which has Autolayout disabled.
    [[UINib nibWithNibName:@"NotRotatingView" bundle:[NSBundle bundleForClass:self.class]] instantiateWithOwner:self options:nil];
    [self.view addSubview:self.notRotatingView];
}


История версии документа


ДатаПримечания
27.03.2015

Новый документ, описывающий, как 'заблокировать' ориентацию представления, позволяя остальной части интерфейса вращаться.