Is it possible to push a View Controller with a completion block?
The better solution would be wrapping the push animation by an CATransaction and set the completionBlock. There's no need to deal with timings.
[CATransaction begin];
[CATransaction setCompletionBlock:^{
//whatever you want to do after the push
}];
[[self navigationController] pushViewController:viewController animated:YES];
[CATransaction commit];
justMartin's answer worked great for me. For those new to using swift API:
CATransaction.begin()
navigationController?.pushViewController(viewController, animated: true)
CATransaction.setCompletionBlock({
//your post animation logic
})
CATransaction.commit()
Not sure if I understand correctly, but I pushed a view controller in a completion block as follows. In a table view controller, added the following line to the header file:
typedef void(^myCompletion)(BOOL);
Then in the class itself, added the following method:
-(void) myMethod:(myCompletion) compblock
{
compblock(YES);
}
Now in didSelectRowAtIndexPath
, I called myMethod
and in the completion block, pushed a view controller.
[self myMethod:^(BOOL finished) {
if(finished){
dispatch_async(dispatch_get_main_queue(), ^{
DVSecondTableViewController *vc = [[DVSecondTableViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
});
}
}];
I'm not sure if it's okay to push view controllers outside of the main thread, so I embedded that call in a dispatch_async()
.
Solution with CATransaction
is great but there is another way to do that. You can make your controller a delegate of UINavigationController
and implement didShowViewController
method:
class FooBarController: UIViewController, UINavigationControllerDelegate {
func viewDidLoad() {
self.navigationController?.delegate = self
}
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
// your awesome completion code here
}
}
This approach can be more convenient for your task