The only solution I have seen was an answer to a stackoverflow question. I posted the link below. The answer I am referring is the 5th one. It seems that some users have so
Here is my approach, using a UINavigationController category and method swizzling.
The method -[UINavigationController didShowViewController:animated:] is private, so although it has been reported safe to use, use at you own risks.
Credits goes to this answer for the idea and NSHipster for the method swizzling code. This answer also has an interesting approach.
//
// UINavigationController+Additions.h
//
@interface UINavigationController (Additions)
@property (nonatomic, getter = isViewTransitionInProgress) BOOL viewTransitionInProgress;
@end
//
// UINavigationController+Additions.m
//
#import "UINavigationController+Additions.h"
#import
static void *UINavigationControllerViewTransitionInProgressKey = &UINavigationControllerViewTransitionInProgressKey;
@interface UINavigationController ()
// Private method, use at your own risk.
- (void)didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
@end
@implementation UINavigationController (Additions)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector1 = @selector(pushViewController:animated:);
SEL swizzledSelector1 = @selector(zwizzledForViewTransitionInProgress_pushViewController:animated:);
Method originalMethod1 = class_getInstanceMethod(class, originalSelector1);
Method swizzledMethod1 = class_getInstanceMethod(class, swizzledSelector1);
BOOL didAddMethod1 = class_addMethod(class, originalSelector1, method_getImplementation(swizzledMethod1), method_getTypeEncoding(swizzledMethod1));
if (didAddMethod1) {
class_replaceMethod(class, swizzledSelector1, method_getImplementation(originalMethod1), method_getTypeEncoding(originalMethod1));
} else {
method_exchangeImplementations(originalMethod1, swizzledMethod1);
}
SEL originalSelector2 = @selector(didShowViewController:animated:);
SEL swizzledSelector2 = @selector(zwizzledForViewTransitionInProgress_didShowViewController:animated:);
Method originalMethod2 = class_getInstanceMethod(class, originalSelector2);
Method swizzledMethod2 = class_getInstanceMethod(class, swizzledSelector2);
BOOL didAddMethod2 = class_addMethod(class, originalSelector2, method_getImplementation(swizzledMethod2), method_getTypeEncoding(swizzledMethod2));
if (didAddMethod2) {
class_replaceMethod(class, swizzledSelector2, method_getImplementation(originalMethod2), method_getTypeEncoding(originalMethod2));
} else {
method_exchangeImplementations(originalMethod2, swizzledMethod2);
}
});
}
- (void)zwizzledForViewTransitionInProgress_pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewTransitionInProgress) {
LogWarning(@"Pushing a view controller while an other view transition is in progress. Aborting.");
} else {
self.viewTransitionInProgress = YES;
[self zwizzledForViewTransitionInProgress_pushViewController:viewController animated:animated];
}
}
- (void)zwizzledForViewTransitionInProgress_didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[self zwizzledForViewTransitionInProgress_didShowViewController:viewController animated:YES];
self.viewTransitionInProgress = NO;
}
- (void)setViewTransitionInProgress:(BOOL)viewTransitionInProgress
{
NSNumber *boolValue = [NSNumber numberWithBool:viewTransitionInProgress];
objc_setAssociatedObject(self, UINavigationControllerViewTransitionInProgressKey, boolValue, OBJC_ASSOCIATION_RETAIN);
}
- (BOOL)isViewTransitionInProgress
{
NSNumber *viewTransitionInProgress = objc_getAssociatedObject(self, UINavigationControllerViewTransitionInProgressKey);
return [viewTransitionInProgress boolValue];
}
@end