Ориентация в UIView добавлена ​​в UIWindow

У меня есть UIView, который должен покрывать все устройство (UIWindow), чтобы поддерживать эффект увеличения/уменьшения изображения, который я делаю, используя базовую анимацию, когда пользователь нажимает кнопку на UITableViewCell, и я масштабирую связанное изображение.

Масштабирование выполняется безупречно, что я не смог выяснить, почему subview все еще находится в портретном режиме, даже если устройство находится в ландшафте. Иллюстрация ниже:

enter image description here

У меня есть контроллер навигации, но это представление было добавлено непосредственно в UIWindow.

Ответ 1

Вы можете прочитать о некоторых из возможных причин здесь:
Техническое Q & A QA1688 - Почему мой UIViewController не будет вращаться вместе с устройством?

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

UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) 
    window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:myView];    

Ответ 2

Проблема

Начиная с iOS 6, только верхний контроллер вида (рядом с Объект UIApplication) участвует в принятии решения о ответ на изменение ориентации устройства.

https://developer.apple.com/library/content/qa/qa1688/_index.html

Решение

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

Код

Он поддерживает любую комбинацию версий системы SDK и iOS. Соответствующий код можно найти здесь: https://github.com/hfossli/AGWindowView/blob/master/Source/AGWindowView.m

Ответ 3

Я создал категорию в UIApplication, которая имеет свойство helper и метод для получения первого подзаголовка keyWindow. Это мнение, которое вы хотите наложить в любом случае. Теперь, когда вы добавляете представление, которое управляется UIViewController к этому представлению, вызывается метод shouldRotateToInterfaceOrientation:.

UIApplication + WindowOverlay.h

#import <UIKit/UIKit.h>

@interface UIApplication(WindowOverlay)

    @property (nonatomic, readonly) UIView *baseWindowView;

    -(void)addWindowOverlay:(UIView *)view;

@end

UIApplication + WindowOverlay.m

#import "UIApplication+WindowOverlay.h"

@implementation UIApplication(WindowOverlay)

    -(UIView *)baseWindowView{
        if (self.keyWindow.subviews.count > 0){
            return [self.keyWindow.subviews objectAtIndex:0];
        }
        return nil;
    }

    -(void)addWindowOverlay:(UIView *)view{
        [self.baseWindowView addSubview:view];
    }
@end

и вот как вы его используете.

//at the top of the file...or in {yourproject}.pch
#import "UIApplication+WindowOverlay.h

//in a method:

UIView *view = [UIView new];

UIView *window = [UIApplication sharedApplication].baseWindowView;

view.frame = window.bounds;

[window addSubview:view];

//or

[[UIApplication sharedApplication] addWindowOverlay:view];

Ответ 4

Это связано с тем, что, поскольку вы упоминаете, что ваше представление было добавлено непосредственно в UIWindow, поэтому, когда метод для вращения вызывается для контроллера навигации, с uiview ничего не происходит. UIView будет вращаться, если это будет подчинено представлению контроллера вида. Если по какой-то причине это невозможно сделать. Затем вы можете переопределить этот метод:

// This method is called every time the device changes orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
}

И каждый раз, когда меняется ваша ориентация, вы также меняете ориентацию вашего представления.

Ответ 6

Другое решение, как я решил эту проблему.

Определите текущую ориентацию:

@interface AJImageCollectionViewController (){
    UIInterfaceOrientation _currentOrientation;
}
@end

Затем проверьте ориентацию в viewWillLayoutSubviews:

- (void)viewWillLayoutSubviews {
    [self checkIfOrientationChanged];
}

- (void)checkIfOrientationChanged {
    UIInterfaceOrientation newOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    BOOL newOrientationIsPortrait = UIInterfaceOrientationIsPortrait(newOrientation);
    BOOL oldOrientationIsPortrait = UIInterfaceOrientationIsPortrait(_currentOrientation);

    // Check if the orientation is the same as the current
    if(newOrientationIsPortrait != oldOrientationIsPortrait){
        _currentOrientation = newOrientation;
        // Do some stuff with the new orientation
    }
}