Контроллер модального представления не запускается в ландшафтном режиме

У меня есть приложение на основе навигации с подробным представлением (UIWebView) с кнопками действий внизу в UIToolbar. Я хочу добавлять «заметки» при нажатии кнопки «заметки». Все работает нормально, когда веб-просмотр находится в портретном режиме. Нажимаю кнопку заметок, модальный вид открывается нормально и отлично работает.

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

У меня есть еще одна кнопка, которая вызывает редактор писем, который ведет себя точно так же. Вот код в моем UIWebViewController:

- (IBAction)addNotes:(id)sender 
{
    NotesViewController *notesViewController;

    // create the view controller and set it as the root view of a new navigation
    // controller

    notesViewController = [[NotesViewController alloc] initWithPrimaryKey:self.record.primaryKey];
    UINavigationController *newNavigationController =  
    [[UINavigationController alloc] initWithRootViewController:notesViewController];

    // present the navigation controller modally

    [self presentModalViewController:newNavigationController animated:YES];
    [notesViewController release]; 
    [self.view setNeedsDisplay]; // not sure if I need this!  I was trying different things...
    [self.devotionText setNeedsDisplay]; // ditto...
    [newNavigationController release];
}

Любые идеи? Я пробовал много разных вещей, но безрезультатно. У меня просто белый экран без панели навигации (хотя вверху есть строка состояния).


person Glasswing    schedule 22.09.2010    source источник
comment
Вы используете последнюю версию ОС? У меня были проблемы с продвижением модального режима только в альбомной ориентации в портретном режиме на 3.1.3 ...   -  person tc.    schedule 23.09.2010
comment
Да, я использую 4.0 SDK ...   -  person Glasswing    schedule 23.09.2010


Ответы (7)


Модальные окна не всегда получают информацию о поворотах, и они получают информацию из строки состояния, что не всегда работает правильно. Поместите это в свой viewWillAppear, чтобы исправить: [UIApplication sharedApplication].statusBarOrientation = self.interfaceOrientation И, если вы хотите, чтобы контроллер навигации был внутри вашего модального окна, вам нужно его создать.

Кроме того, вам не нужен setNeedsDisplay. Это влияет только на текущие представления, а не на модальное окно, которое вы представляете.

person MishieMoo    schedule 22.09.2010
comment
Спасибо, что ответили так быстро! Я попытался поместить код statusBarOrientation в свой NotesViewController viewWillAppear, но по-прежнему получаю такое же поведение! Я также удалил новый контроллер навигации и по-прежнему ничего не получаю ... только белый экран. Есть другие предложения? - person Glasswing; 22.09.2010
comment
Можете ли вы опубликовать код для функции initWithPrimaryKey? Размещение кода в этом файле очень поможет! - person MishieMoo; 22.09.2010
comment
Функция init проста ... файл xib - это просто UIView с UITextView под ним. - person Glasswing; 22.09.2010
comment
На самом деле перо - это просто UIView, и я создаю UITextView программно. (Я пробовал оба способа ...) - person Glasswing; 22.09.2010
comment
Вы пробовали регистрировать свои подвиды? Добавьте NSLog в viewWillAppear, который распечатывает subviews (self.view.subviews), чтобы убедиться, что ваши текстовые поля действительно создаются. Они? Вы прошли через это в отладчике? - person MishieMoo; 23.09.2010
comment
Ага. Текстовое представление создается. Я установил фоновый вид на синий, а текстовый - на красный (для отладки). Я даже закомментировал создание подвида textview. Когда я открываю вид заметок (синий) в альбомной ориентации, он по-прежнему показывает белый экран (не синий). Думаю, может дело в фреймах / макетах / слоях? Я в полном тупике ... - person Glasswing; 24.09.2010

Ответ здесь:

https://stackoverflow.com/a/10250747/1449618

Use the window's root view controller to present:

[self.view.window.rootViewController presentViewController:masterView
                                                  animated:YES
                                                completion:NULL];
person Jimmy_m    schedule 03.08.2012

Ух ты, я потерял дни над этой проблемой ... но я нашел решение!

У меня была та же проблема, что и у вас: метод presentModalViewController: animated: работал только в портретном режиме.

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

Итак, у моего корневого контроллера представления был объект корневого представления и несколько контроллеров дочерних представлений. Когда дочерний контроллер представления был активирован, его объект представления был добавлен как подпредставление к представлению корневого контроллера представления.

Методу presentModalViewController это не понравилось. Однако, как только я установил свойство "parentViewController" дочерних контроллеров представления, все заработало!

Проблема только в том, что parentViewController - свойство только для чтения. Вам необходимо расширить класс UIViewController, чтобы вы могли получить к нему доступ.

@interface UIViewController (HelperExtension)

@property (nonatomic, assign) UIViewController *parent;

@end

@implementation UIViewController (HelperExtension)

- (UIViewController *)parent
{
    return self.parentViewController;
}

- (void)setParent:(UIViewController *)parent
{
    [self setValue:parent forKey:@"_parentViewController"];
}

@end

Итак, всякий раз, когда вы добавляете представление дочернего контроллера представления к родительскому контроллеру представления, после этого вызывайте метод «setParent:». Тогда все заработает!

person PrimaryFeather    schedule 04.11.2010
comment
Это тоже сработало для меня. Вы ведь не использовали BCTabBarController ни при каких изменениях? Так много проблем с этими маленькими анимированными стрелками ... - person Craig McMahon; 02.12.2011

Возникла та же проблема при модальном представлении контроллера навигации. Обязательно правильно реализовать: shouldAutorotateToInterfaceOrientation

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    BOOL shouldAutorotate = NO;
    if( isControllerMangingAllOrientations )
    {
        shouldAutorotate = YES;
    }
    else
    {
        shouldAutorotate = (toInterfaceOrientation == UIInterfaceOrientationPortrait);
    }
    return shouldAutorotate;
}

Я устанавливал логическое значение в методе viewDidLoad, не очень хорошая идея. Помещение его в метод initWithNibName: bundle: - правильное место.

person ıɾuǝʞ    schedule 16.11.2011
comment
боролся именно с этой проблемой и забыл, что по умолчанию XCode 4 добавляет: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return (interfaceOrientation == UIInterfaceOrientationPortrait); } Неудивительно, что это всегда был портрет .... вздох - person Josh Peak; 29.06.2012

Если вы используете PresentModalViewController только для анимации, как я, вы можете использовать pushViewController с анимацией, как показано ниже;

Отображение анимации pushviewcontroller выглядит как presentModalViewController

и вы можете закрыть viewController, как показано ниже;

CATransition* transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;

[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];

Надеюсь, поможет..

person seymatanoglu    schedule 11.06.2014

У меня была задача показать видеоплеер в ландшафтном режиме.

AVPlayerViewController *playerViewController = [AVPlayerViewController new];
//Player init code goes here....

// #define degreesToRadian(x) (M_PI * (x) / 180.0) - was defined previously in a class header

playerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
playerViewController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
playerViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

[self presentViewController:playerViewController animated:YES completion:nil];
person David    schedule 04.08.2015

Вам не нужен новый элемент управления навигацией. r.

- (IBAction)addNotes:(id)sender {

 NotesViewController *notesViewController;

 // create the view controller and set it as the root view of a new navigation
 // controller

 notesViewController = [[NotesViewController alloc] initWithPrimaryKey:self.record.primaryKey];

 [self.navigationController pushViewController: notesViewController animated: YES];
 [notesViewController release];
}
person Stephen Furlani    schedule 22.09.2010
comment
Я удалил контроллер навигации, но поведение по-прежнему остается прежним. Большое спасибо за ответ. Есть другие идеи? - person Glasswing; 22.09.2010