Подтвердить что ты не робот

Можно ли нажать View View с блоком завершения?

Документация UINavigationController не содержит методов pushViewController с параметром completion:.

4b9b3361

Ответ 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;
            }];
        }
    }
}