Ориентация в UIView добавлена ​​в UIWindow - PullRequest
44 голосов
/ 24 марта 2010

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

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

enter image description here

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

Ответы [ 6 ]

121 голосов
/ 30 июля 2010

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

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

UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) 
    window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:myView];    
83 голосов
/ 10 февраля 2011

проблема

Начиная с 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

4 голосов
/ 02 марта 2011

Я создал категорию в UIApplication, у которой есть вспомогательное свойство и метод для получения первого подпредставления 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];
1 голос
/ 24 марта 2010

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

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

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

0 голосов
/ 30 мая 2013

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

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

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

Затем проверьте ориентацию в представленииWillLayoutSubviews:

- (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
    }
}
0 голосов
/ 22 апреля 2010

У меня была похожая проблема с представлениями, добавляемыми непосредственно в окно. Может быть, это поможет: Автоматическое определение размера UIView после добавления в окно

...