Updated answer:
I prefer this solution by nonamelive
on Github to what I originally posted: https://gist.github.com/nonamelive/9334458. By subclassing the UINavigationController
and taking advantage of the UINavigationControllerDelegate
, you can establish when a transition is happening, prevent other transitions from happening during that transition, and do so all within the same class. Here's an update of nonamelive's solution which excludes the private API:
#import "NavController.h"
@interface NavController ()
@property (nonatomic, assign) BOOL shouldIgnorePushingViewControllers;
@end
@implementation NavController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (!self.shouldIgnorePushingViewControllers)
{
[super pushViewController:viewController animated:animated];
}
self.shouldIgnorePushingViewControllers = YES;
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
self.shouldIgnorePushingViewControllers = NO;
}
@end
Previous answer:
Problem with this Previous Answer: isBeingPresented
and isBeingDismissed
only work in viewDidLoad:
or viewDidApper:
Although I haven't tested this myself, here is a suggestion.
Since you're using a UINavigationController
, you can access the contents of your navigation stack, like so:
NSArray *viewControllers = self.navigationController.viewControllers;
And through that array of view controllers, you can access some or all relevant indices if need be.
Luckily, two especially convenient methods were introduced in iOS 5: isBeingPresented and isBeingDismissed which return "YES" if the view controller is in the process of being presented or being dismissed, respectively; "NO" otherwise.
So, for example, here's one approach:
NSArray *viewControllers = self.navigationController.viewControllers;
for (UIViewController *viewController in viewControllers) {
if (viewController.isBeingPresented || viewController.isBeingDismissed) {
// In this case when a pop or push is already in progress, don't perform
// a pop or push on the current view controller. Perhaps return to this
// method after a delay to check this conditional again.
return;
}
}
// Else if you make it through the loop uninterrupted, perform push or pop
// of the current view controller.
In actuality, you probably won't have to loop through every view controller on the stack, but perhaps this suggestion will help set you off on the right foot.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…