Как установить ориентацию второго UIWindow

У меня есть следующий код в моей основной функции ViewController viewDidLoad

window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];


nav = [[NavWithAutoRotateViewController alloc] initWithRootViewController:self];

[window addSubview:[nav view]];
[window makeKeyAndVisible];


[[self navigationController] setNavigationBarHidden:YES];

Мое приложение для iPad в настоящее время настроено на работу только в ландшафтном режиме, и я использую это новое окно, чтобы показать документ быстрого просмотра и разрешить панели навигации предоставить кнопку «Назад» и параметры сохранения для документа. Основная проблема заключается в том, что новая ориентация UIWindow не соответствует UIWindow моих основных приложений.

У меня есть пользовательский UINavigationController, названный выше NavWithAutoRotateController, и вот код для этого контроллера.

-(id)init
{
    if(self)
    {
//        _supportedInterfaceOrientatoin = UIInterfaceOrientationMaskLandscape;
//        _orientation = UIInterfaceOrientationLandscapeLeft;
    }


    return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}


// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationMaskLandscape;
}

person mattwallace    schedule 15.08.2013    source источник
comment
У меня такая же проблема, вам удалось ее решить?   -  person Piotr Wach    schedule 15.09.2013


Ответы (3)


Думаю, у меня есть решение. Проблема, похоже, заключается в назначении UIViewController rootViewController в вашем дополнительном UIWindow.

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

Чтобы решить эту проблему, я сделал следующее:

UIWindow *newWindow = [[UIWindow alloc] initWithFrame: [UIApplication sharedApplication].keyWindow.frame];
newWindow.windowLevel = UIWindowLevelStatusBar+1;
// You can use a view controller instantiated from a xib or storyboard here if you want.
// Just don't use the view controller already set as a UIWindow's rootViewController.
UIViewController *newViewController = [[UIViewController alloc] init];
newWindow.rootViewController = newViewController;
[newWindow makeKeyAndVisible];
// Add something to the new UIWindow. Can use the new UIViewController's view:
[newViewController.view addSubview: myContentView];
// Or could add it as subview of UIWindow: - either works.
[newWindow addSubview: myContentView];

Таким образом, похоже, были решены все странные проблемы, связанные с вращением. Надеюсь это поможет.

person Simon Tillson    schedule 13.05.2015

У меня была такая же проблема. Изменения ориентации правильно обрабатывались с помощью метода viewWillTransition. Но моя проблема заключалась в том, что в некоторых крайних случаях, а именно, если мое устройство располагалось под странным углом, настраиваемый UIWindow инициализировался в портретной ориентации, даже если rootViewController был в альбомной ориентации. И viewWillTransition не вызывается, потому что устройство не вращается при начальной загрузке. Я нашел действительно простое решение своей проблемы, которое работало в любой ситуации, которую я тестировал. Сначала инициализируйте свой собственный UIWindow без фрейма. Затем установите рамку. И вуаля... его ориентация соответствует вашим ожиданиям.

Быстрый

let customWindow = UIWindow()
customWindow.frame = CGRect(x: x, y: y, width: w, height: h)
customWindow.rootViewController = self //<your_viewController>
customWindow.windowLevel = .statusBar // or whatever level you need
customWindow.makeKeyAndVisible()

ObjC

UIWindow customWindow = [[UIWindow alloc] init];
customWindow.frame = CGRectMake(x, y, w, h);
customWindow.rootViewController = self;
customWindow.windowLevel = UIWindowLevelStatusBar;
[customWindow makeKeyAndVisible];
person FromTheStix    schedule 29.07.2019
comment
Я рвал на себе волосы, и, как ни удивительно, это сработало! Звучит как фокус-фокус, но по какой-то причине это решает проблему. - person LenK; 05.10.2020
comment
@LenK Рад, что это помогло! Я пришел к выводу, что иногда простое изменение порядка выполнения — это то, что имеет значение. - person FromTheStix; 07.10.2020

Зарегистрируйтесь для уведомления об изменении рамки строки состояния, которое вызывается (афаик) только при изменении ориентации, а затем определите ориентацию вашего нового окна.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(appWillChangeStatusBarFrameNotification:)
                                             name:UIApplicationWillChangeStatusBarFrameNotification
                                           object:nil];
person Ashok    schedule 16.08.2013
comment
что, если ориентация уже альбомная, когда этот вид загружается, и он загружается как портрет? - person mattwallace; 19.08.2013
comment
@mattwallace Немного поздно, но посмотри мой ответ. У меня была именно эта проблема... rootViewController уже загружен в альбомной ориентации, но мой пользовательский интерфейс UIWindow загружался в портретной ориентации. - person FromTheStix; 29.07.2019