После dismissModalViewControllerAnimated родительского вида находится в полноэкранном режиме


После каждого отключения ModalViewController родительское представление устанавливается в полноэкранный режим. Почему?

Before                After
+----------------+   +------------------+
|head            |   | detailview       |
+----------------+   |                  |
|detailview      |   |                  |
|                |   |                  |
|                |   |                  |
|                |   |                  |
+----------------+   +------------------+

Я создал" простой " пример проекта, в котором появляется ошибка.

Http://github.com/rphl/modalTest

Пожалуйста, взгляните на него.
4 4

4 ответа:

Это своего рода догадка, но обоснованная догадка после того, как вы немного поиграли с вашим кодом.

Когда вы представляете модальный вид, он добавляется в качестве подвида вида, принадлежащего контроллеру, на котором был вызван presentModalViewController. Поскольку модальное представление предназначено для отображения в полноэкранном режиме, это будет выглядеть так, как если бы внутри кадр супервизора был сделан в полноэкранном режиме.

Я помещаю следующее в ваш MyDetailViewController:

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = self.navigationController.view.frame;
    NSLog(@"%@", NSStringFromCGRect(frame));
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    CGRect frame = self.navigationController.view.frame;
    NSLog(@"%@", NSStringFromCGRect(frame));
}

Что привело к следующий вывод:

2010-09-19 00:23:51.823 ModalTest[2478:207] {{0, 164}, {320, 316}}
2010-09-19 00:23:56.178 ModalTest[2478:207] {{0, 0}, {320, 480}}

Первая строка была выведена, когда деталь впервые появилась. Вторая строка выводилась, когда модальное представление было отклонено.

На самом деле мне не особенно нравится решение, которое я нашел, но это имеет желаемый эффект. В вашем методе sendMail:
ModalTestAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.viewController presentModalViewController:controller animated:YES];

И в вашем mailComposeController:didFinishWithResulterror: методе:

ModalTestAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];

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

Что-то, что работает для меня, было восстановить кадр после того, как модальный контроллер вида будет отклонен. Пример кода:

Представление Модального Контроллера Вида

[self presentModalViewController:self.modalViewController animated:YES];

Отклонение Модального Контроллера Вида

CGRect frame = self.view.frame;
[self.modalViewController dismissModalViewControllerAnimated:YES];
self.view.frame = frame;

У меня возникла эта проблема после подготовки моего приложения для iPhone для iPad. Это оказалось чем-то очень странным, и мне потребовалось несколько часов, чтобы найти его. Это было связано с авторотацией.

Для:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

Я возвращался нет

Ранее я возвращался:

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

По какой-то причине возврат No привел к тому, что панель навигации оказалась под строкой состояния после отключения контроллера модального вида.

Этот вопрос был задан очень давно, но я хотел бы помочь другим, поделившись своим опытом, потому что мне потребовалось некоторое время, чтобы понять это.

У меня есть контроллер, который вставляется в навигационный контроллер, который сам является первой вкладкой в UITabBarController. Из моего контроллера я представляю контроллер модального вида, который воспроизводит полноэкранное видео с помощью MPMoviePlayerController. Когда видео заканчивается, я программно закрываю контроллер модального вида и возвращаюсь к предыдущему экрану. Но иногда после при увольнении строка состояния исчезла, а панель навигации была изменена, чтобы занять место строки состояния. В других случаях панель навигации была наполовину обрезана и выглядела так, как будто она находится под строкой состояния. Это поведение было замечено в большинстве случаев, но не всегда, что делало его очень запутанным. Я пробовал много вещей, которые другие люди здесь на StackOverflow предлагают, среди которых было явно скрывать строку состояния в viewWillAppear:, возвращая YES по крайней мере для одной ориентации в shouldAutorotateToInterfaceOrientation:, представляя контроллер модального вида из навигационного контроллера или даже контроллера панели вкладок (который является корневым контроллером вида моего окна), отклоняя метод протокола вместо вызова dismissViewControllerAnimated:completion: непосредственно из контроллера модального вида, играя с MPMoviePlayerController уведомлениями и состояниями. Казалось, ничто не могло помочь. В конце концов я понял, что мои проблемы возникают только тогда, когда видео заканчивается и элементы управления видео (включая строку состояния) скрыты. Я полагаю, что это потому, что мой модальный контроллер вида является полноэкранным (имеет свойство wantsFullScreenLayout, установленное в YES) и представлен из контроллера вида внутри навигационного контроллера и контроллера панели вкладок, когда строка состояния скрыта в момент увольнения, это заставляет навигационный контроллер изменять размер своего дочернего контроллера вида и заполнять экран, скрывая строку состояния или подсвечивая ее. Я действительно смог увидеть это, записав размер моего DetailsViewController (тот, который помещается внутри навигации контроллер).

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

1. Представление контроллера модального вида из DetailsViewController

[self presentViewController:controller animated:YES completion:NULL];  

2. Отклонение модального контроллера вида от самого себя

[[UIApplication sharedApplication] setStatusBarHidden:NO];  
[self dismissViewControllerAnimated:YES completion:nil];