是否可以使用完成块推送View Controller?

时间:2014-02-13 02:04:08

标签: ios uiviewcontroller uinavigationcontroller pushviewcontroller

UINavigationController的文档不包含带pushViewController参数的completion:方法。

6 个答案:

答案 0 :(得分:61)

更好的解决方案是通过CATransaction包装推送动画并设置completionBlock。没有必要处理时间问题。

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    //whatever you want to do after the push
}];
[[self navigationController] pushViewController:viewController animated:YES];
[CATransaction commit];

答案 1 :(得分:12)

只是马丁的答案对我很有帮助。对于那些使用swift API的新手:

CATransaction.begin()
navigationController?.pushViewController(viewController, animated: true)
CATransaction.setCompletionBlock({ 
    //your post animation logic
})
CATransaction.commit()

答案 2 :(得分:5)

使用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 
  }
}

这种方法可以更方便您的任务

答案 3 :(得分:2)

不确定我是否理解正确,但我按如下方式在完成块中推送了一个视图控制器。在表视图控制器中,将以下行添加到头文件中:

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()

答案 4 :(得分:0)

尝试使用-[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;
            }];
        }
    }
}

答案 5 :(得分:-9)

我会选择@ justMartin的回答。但下面是另一种方法。

推动动画需要0.3秒。所以,如果你想在完成后在这里运行一些函数,请在0.3秒的延迟后使用performSelector。

[self performSelector:@selector(completedPushing:) withObject:nil afterDelay:.3];


 将new viewController推到navigation stack后,old viewController view将从视图层次结构中删除。这会导致在旧ViewController上调用viewDidDisappear。您可以编写completion那里有代码。不要忘记在viewDidDisappear的某个实现点调用super