See par’s answer for another and more up to date solution
UINavigationController animations are run with CoreAnimation, so it would make sense to encapsulate the code within CATransaction and thus set a completion block.
Swift:
For swift I suggest creating an extension as such
extension UINavigationController {
public func pushViewController(viewController: UIViewController,
animated: Bool,
completion: @escaping (() -> Void)?) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
pushViewController(viewController, animated: animated)
CATransaction.commit()
}
}
Usage:
navigationController?.pushViewController(vc, animated: true) {
// Animation done
}
Objective-C
Header:
#import <UIKit/UIKit.h>
@interface UINavigationController (CompletionHandler)
- (void)completionhandler_pushViewController:(UIViewController *)viewController
animated:(BOOL)animated
completion:(void (^)(void))completion;
@end
Implementation:
#import "UINavigationController+CompletionHandler.h"
#import <QuartzCore/QuartzCore.h>
@implementation UINavigationController (CompletionHandler)
- (void)completionhandler_pushViewController:(UIViewController *)viewController
animated:(BOOL)animated
completion:(void (^)(void))completion
{
[CATransaction begin];
[CATransaction setCompletionBlock:completion];
[self pushViewController:viewController animated:animated];
[CATransaction commit];
}
@end