Как выполнить переход после завершения текущей презентации

У меня есть ситуация в моем приложении, когда мне нужно отклонить контроллер модального представления через раскрутку перехода, а затем сразу после этого представить другой контроллер модального представления. Для этого я просто задерживаю вызов для представления нового контроллера представления на 1,0 секунды. Это может не работать все время, возможно, если по какой-то причине закрытие занимает больше времени, второй контроллер представления не сможет появиться, потому что происходит переход. Я только что столкнулся с этой ситуацией, хотя в этом случае это сработало. Это было зарегистрировано:

Предупреждение. Попытка начать презентацию во время ее проведения!

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

Как я могу закрыть модальный контроллер представления, а затем представить новый, всегда гарантируя отсутствие конфликта?

Это мое текущее решение:

[self performSegueWithIdentifier:@"Unwind Segue" sender:self]; //dismiss modal or pushed VC

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [tabBarController performSegueWithIdentifier:@"Show New VC" sender:self]; //present new modal VC
});

person Jordan H    schedule 17.07.2014    source источник
comment
Почему бы не подарить новый модальный контроллер от текущего, а не раскручивать сначала? Какой смысл раскручиваться, чтобы тут же предъявить еще один?   -  person rdelmar    schedule 18.07.2014
comment
Я возвращаюсь туда, где видна панель вкладок, затем выполняю переход, потому что этот переход определен только для tabBarController. Это сложное приложение с множеством экранов, и я не хотел создавать переход к этому контроллеру представления из каждого отдельного контроллера представления. Кроме того, в этом сценарии действительно желательно вернуться на главную страницу.   -  person Jordan H    schedule 18.07.2014
comment
Я думаю, у вас должна быть возможность вызывать PerformSegue в методе viewDidAppear контроллера, на который вы разворачиваетесь. Вы можете установить флаг в методе раскрутки и проверить это в viewDidAppear, чтобы узнать, следует ли вам выполнять PerformSegue или нет.   -  person rdelmar    schedule 18.07.2014
comment
Это интересное решение. Я попробую это, спасибо!   -  person Jordan H    schedule 18.07.2014
comment
Как насчет использования viewDidDisappear контроллера представления, который раскручивается? Например, как только он исчезнет, ​​скажите родительскому контроллеру представления выполнить переход.   -  person Eric Amorde    schedule 18.07.2014


Ответы (2)


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

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"transitioned to new controller!" object:nil]];
}

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

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedNotification:) name:@"transitioned to new controller!" object:nil];

Не забудьте прекратить прослушивание после получения уведомления (если вы не хотите продолжать наблюдать) за этим уведомлением, иначе вы продолжите наблюдать за всеми уведомлениями в своем приложении:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"transitioned to new controller!" object:nil];
person Raymond Array Wang    schedule 18.07.2014
comment
Спасибо, что предложили использовать уведомления. Я использовал это вместе с предложением Эрика Аморда использовать viewDidDisappear и предложением rdelmar использовать логическое значение, чтобы узнать, следует ли переходить после увольнения. Спасибо всем! - person Jordan H; 18.07.2014

Мне потребовалось некоторое время, чтобы понять это самому. iOS 7 представила transitionCoordinator, который присутствует только в UIViewController во время анимации. Короче говоря, вы должны зарегистрировать свой блок завершения в другом потоке в основной очереди (который будет запущен после запуска анимации).

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // ... prepare your for segue

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.transitionCoordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
         {
             // Segue animation complete
         }];
    });
}
person dhallman    schedule 20.01.2015
comment
вы должны зарегистрировать свой блок завершения в другом потоке. Это не другой поток, он запускается (позже) в (том же) основном потоке. - person Pang; 18.05.2018