2014-07-16 57 views

回答

2

在我的經驗,在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