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

问题描述 投票:16回答:6

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

ios uiviewcontroller uinavigationcontroller pushviewcontroller
6个回答
-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


61
投票

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

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

12
投票

justMartin的回答对我很有帮助。对于那些使用swift API的新手:

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

6
投票

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

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


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


1
投票

尝试使用-[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;
            }];
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.