IOS 6: Родительский модальный модальный ПрезентацияStyle игнорируется после вращения

С iPad с iOS6 у нас есть эта ошибка, когда модальный контроллер просмотра будет расширяться до полного экрана, даже если ему сообщают используйте стиль презентации "форма листа". Но это происходит, только если есть два модала: родительский и его дочерний.

Итак, так создается и представлен первый модал:

UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[parentController presentModalViewController:navigationController animated:YES];
// parentController is my application root controller

Вот как создается и представляет собой дочерний модал:

UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[parentController presentModalViewController:navigationController animated:YES];
// parentController is the navigationController from above

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

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

Обратите внимание, что это происходит только на iOS6 (устройство и симулятор) и не происходит на iOS 5 (симулятор и сообщается для работы тестировщиками).

До сих пор я пробовал следующее без успеха:

  • настройка wantsFullScreenLayout - NO
  • принудительно wantsFullScreenLayout всегда возвращать NO, переопределяя его
  • Включение некоторых контроллеров внутри контроллера навигации также указывает UIModalPresentationFormSheet
  • реализация preferredInterfaceOrientationForPresentation
  • обновление до iOS 6.0.1

Спасибо!


UPDATE: Итак, я адаптировал ответ от Форумы разработчиков Apple (https://devforums.apple.com/message/748486#748486), чтобы он работал с несколькими вложенными модальными.

- (BOOL) needNestedModalHack {
    return [UIDevice currentDevice].systemVersion.floatValue >= 6;
}

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                          duration:(NSTimeInterval)duration {

    // We are the top modal, make to sure that parent modals use our size
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.frame = parent.presentedViewController.view.superview.frame;
        }
    }

    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                 duration:(NSTimeInterval)duration {
    // We are the top modal, make to sure that parent modals are hidden during transition
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.hidden = YES;
        }
    }

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    // We are the top modal, make to sure that parent modals are shown after animation
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.hidden = NO;
        }
    }

    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}

Ответ 1

Не уверен, что это следует рассматривать как ошибку, и мне любопытно, что принесет iOS 7, но в настоящее время обходной путь этой проблемы заключается в том, чтобы установить modalPresentationStyle в UIModalPresentationCurrentContext для child-viewController.

Set modalPresentationStyle = UIModalPresentationCurrentContext

Это делает ребенка все еще представленным как FormSheet, но предотвращает изменение размера родителя во весь экран во время ротации.

Дирк

Ответ 2

Здесь я вижу 2 проблемы.

1) в iOS 6 метод presentModalViewController:animated: устарел, попробуйте использовать presentViewController:animated:completion: (несмотря на то, что это может не помочь, вы все равно можете это сделать)

2) В iOS 6 каким-то образом появилось, что контейнерные контроллеры (например, UINavigationController) не возвращают сообщения авторотации своим дочерним элементам. Попробуйте подклассифицировать UINavigationController и переопределите соответствующие методы авторотации, которые будут отправлены всем дочерним элементам. Это может помочь.

Ответ 3

Вам необходимо настроить ваш контроллер навигации после вашего основного вида. Таким образом, вы сможете управлять поворотом в каждом представлении.

Если ваш AppDelegate RootViewController является навигационным контроллером, вы не сможете управлять поворотом с помощью собственных функций.