Документация UINavigationController не содержит методов pushViewController
с параметром completion:
.
Можно ли нажать View View с блоком завершения?
Ответ 1
Я бы пошел с ответом @justMartin. Но ниже - другой подход.
push-анимация занимает 0,3 секунды. Поэтому, если вы хотите запустить некоторую функцию здесь после завершения, используйте performSelector после 0,3 секунды задержки.
[self performSelector:@selector(completedPushing:) withObject:nil afterDelay:.3];
ИЛИ
После нажатия new viewController
на navigation stack
, old viewController view
удаляется из иерархии представлений. Это приводит к вызову viewDidDisappear
на старый ViewController. Здесь вы можете написать код completion
. не забудьте вызвать super
в какой-то момент реализации viewDidDisappear.
Ответ 2
Лучшим решением было бы обернуть анимацию push с помощью транзакции CAT и установить блок завершения. Там нет необходимости иметь дело с таймингами.
[CATransaction begin];
[CATransaction setCompletionBlock:^{
//whatever you want to do after the push
}];
[[self navigationController] pushViewController:viewController animated:YES];
[CATransaction commit];
Ответ 3
justMartin ответ отлично поработал у меня. Для новых пользователей, использующих быстрый API:
CATransaction.begin()
navigationController?.pushViewController(viewController, animated: true)
CATransaction.setCompletionBlock({
//your post animation logic
})
CATransaction.commit()
Ответ 4
Решение с CATransaction
велико, но есть и другой способ сделать это. Вы можете сделать ваш контроллер делегатом UINavigationController
и реализовать метод didShowViewController
:
class FooBarController: UIViewController, UINavigationControllerDelegate {
func viewDidLoad() {
self.navigationController?.delegate = self
}
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
// your awesome completion code here
}
}
Этот подход может быть более удобным для вашей задачи
Ответ 5
Не уверен, правильно ли я понимаю, но я нажал контроллер представления в блоке завершения следующим образом. В контроллере табличного представления в файл заголовка добавлена следующая строка:
typedef void(^myCompletion)(BOOL);
Затем в самом классе добавлен следующий метод:
-(void) myMethod:(myCompletion) compblock
{
compblock(YES);
}
Теперь в didSelectRowAtIndexPath
я вызвал myMethod
и в блоке завершения нажал контроллер вида.
[self myMethod:^(BOOL finished) {
if(finished){
dispatch_async(dispatch_get_main_queue(), ^{
DVSecondTableViewController *vc = [[DVSecondTableViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
});
}
}];
Я не уверен, правильно ли нажать контроллеры просмотра вне основного потока, поэтому я включил этот вызов в dispatch_async()
.
Ответ 6
Попробуйте использовать -[UIViewControllerTransitionCoordinator animateAlongsideTransitionInView:animation:completion:]
:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (!self.isPushing) {
self.pushing = YES;
[super pushViewController:viewController animated:animated];
if (!self.transitionCoordinator) {
self.pushing = NO;
} else {
[self.transitionCoordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.pushing = NO;
}];
}
}
}