0
我剛剛出現崩潰,顯示爲以下屏幕快照,它發生在我點擊導航欄上的後退按鈕時,是否有任何典型情況會導致此崩潰?UINavigationController正在進行交易時發生崩潰
我剛剛出現崩潰,顯示爲以下屏幕快照,它發生在我點擊導航欄上的後退按鈕時,是否有任何典型情況會導致此崩潰?UINavigationController正在進行交易時發生崩潰
在我的經驗,在iOS的7引入了一個問題,從而有可能爲你在另一個之前已經結束,最終導致此崩潰開始的過渡。您可以手動複製此,如果你把2導航叫背靠背並運行它們,如:
[self.navigationController pushViewController:whatever animated:YES];
[self.navigationController pushViewController:whatever2 animated:YES];
如果你這樣做,你最終會發現碰撞發生。
我發現確保永不發生的最簡單方法是將UINavigationController
繼承並實現UINavigationControllerDelegate
以防止重疊轉換。
一旦我開始用下面的代碼,我看到由於這個問題已經下降到0
一個要注意的事情崩潰的數量是,如果你確實需要實現另一個<UINavigationControllerDelegate>
你需要寫一些代碼可以自己存儲額外的委託並傳遞委託調用,也許使用NSProxy
或類似的東西。
@interface MyNavigationController() <UINavigationControllerDelegate>
{
// used to prevent "can't add self as subview" crashes which occur when trying to animate 2 transitions simultaneously
BOOL _currentlyAnimating;
}
@end
@implementation MyNavigationController
- (void) viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
- (void) pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(_currentlyAnimating)
{
return;
}
else if(animated)
{
_currentlyAnimating = YES;
}
[super pushViewController:viewController animated:animated];
}
- (UIViewController *) popViewControllerAnimated:(BOOL)animated
{
if(_currentlyAnimating)
{
return nil;
}
else if(animated)
{
_currentlyAnimating = YES;
}
return [super popViewControllerAnimated:animated];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
_currentlyAnimating = NO;
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// tracking cancelled interactive pop
// http://stackoverflow.com/questions/23484310/canceling-interactive-uinavigationcontroller-pop-gesture-does-not-call-uinavigat
[[self transitionCoordinator] notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
if([context isCancelled])
{
UIViewController *fromViewController = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
[self navigationController:navigationController willShowViewController:fromViewController animated:animated];
if([self respondsToSelector:@selector(navigationController:didShowViewController:animated:)])
{
NSTimeInterval animationCompletion = [context transitionDuration] * [context percentComplete];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (uint64_t)animationCompletion * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self navigationController:navigationController didShowViewController:fromViewController animated:animated];
});
}
}
}];
}
@end