OS native is sliding back to the edge of the support, but the full screen, such as QQ global right row back better user experience, obviously not bother to implement it, but to add this functionality problems may cause the interface card after death, the notion of online there are many but not all, in fact there are many kinds of situation, lead to this kind of problem will summarize here:

There are three causes of stuck death:

1. During push or POP, a new swipe back gesture is received.

The main reason is that quick operation of interface switching may appear

Solutions: Custom UINavigationController. In pushViewController/setViewControllers/popViewControllerAnimated/popToRootViewControllerAnimated agents in method - disable gestures (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated; Enable gestures inCopy the code

2. Right-click the root controller to return

Add judgment in the code above and disable gestures if the number of child controllers is 1Copy the code

3. Clicking navigationItem returns the gesture.

Generally appear in the custom the back button, for example: customize button gestures for UIControlEventTouchDown, global rowed back right gestures function view for self. InteractivePopGestureRecognizer. The view, Both can be triggered at the same time

UIView *targetView = [[self.viewControllers lastObject] view]; Or change UIControlEventTouchUpInside button events trigger conditionsCopy the code

Complete add global right swipe return and BUG free code as follows:

@interface LTNavigationController () <UIGestureRecognizerDelegate, UINavigationControllerDelegate > / whether to allow the right slide back * * * / @ property (nonatomic, assign, getter=isBackGestureEnable) BOOL backGestureEnable; @end @implementation LTNavigationController - (void)viewDidLoad { [super viewDidLoad]; self.navigationBar.backgroundColor = [UIColor whiteColor]; // Set the global right swipe return [self setupRightPanReturn]; [self.navigationItemsetHidesBackButton:YES];
    
    self.delegate = self;
}



#pragma mark - generates a return button ---- after each push
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    if (self.viewControllers.count > 0) {
        viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem BarButtonItemWithImg:@"back_black"highlightedImg:nil target:self action:@selector(popViewController)]; viewController.hidesBottomBarWhenPushed = YES; viewController.edgesForExtendedLayout = UIRectEdgeNone; viewController.automaticallyAdjustsScrollViewInsets = NO; } // Disable gestures for pushif ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = NO;
        self.backGestureEnable = NO;
    }
    
    [super pushViewController:viewController animated:animated];
}


- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated{
    for (UIViewController *viewController in viewControllers) {
        if(viewController ! = [viewControllers firstObject]) { viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem BarButtonItemWithImg:@"back_black"highlightedImg:nil target:self action:@selector(popViewController)]; viewController.hidesBottomBarWhenPushed = YES; viewController.edgesForExtendedLayout = UIRectEdgeNone; viewController.automaticallyAdjustsScrollViewInsets = NO; }} // Disable gestures for pushif ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = NO;
        self.backGestureEnable = NO;
    }
    
    [super setViewControllers:viewControllers animated:animated]; } - (void)popViewController{ [self popViewControllerAnimated:YES]; } - (UIViewController *) animated popViewControllerAnimated: (BOOL) {/ / disable gestures when popif ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = NO;
    }
    
    return[super popViewControllerAnimated:animated]; } - (NSArray < > UIViewController * *) animated popToRootViewControllerAnimated: (BOOL) {/ / disable gestures when popif ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = NO;
    }
    
    return[super popToRootViewControllerAnimated:animated]; } - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{// if animated is enabled on the root controller after pushif ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        
        if([navigationController.viewControllers count] == 1) { navigationController.interactivePopGestureRecognizer.enabled = NO;  }else{ self.backGestureEnable = YES; navigationController.interactivePopGestureRecognizer.enabled = YES; }}}Pragma mark -- handles global right slide return --- (void) setupRightPanReturn {/ / acquisition system with sliding gesture of target object id target = self. InteractivePopGestureRecognizer. Delegate; SEL handler = NSSelectorFromString(@)"handleNavigationTransition:"); / / get added system View at the edge of the trigger gesture UIView * targetView = self. InteractivePopGestureRecognizer. View; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget: Target Action: Handler]; pan.delegate = self; [targetView addGestureRecognizer:pan]; / / close the edge trigger gesture To prevent conflict and the original edge gesture [self interactivePopGestureRecognizersetEnabled:NO]; } // When to invoke: Each time the gesture is triggered, the proxy is asked if it is triggered. / / function: Intercept gestures trigger - (BOOL) gestureRecognizerShouldBegin: (gestureRecognizer UIPanGestureRecognizer *) {/ / solve the conflict with the left slide gestures CGPoint translation  = [gestureRecognizer translationInView:gestureRecognizer.view];if(translation.x <= 0 || ! self.isBackGestureEnable) {return NO;
    }
    return self.childViewControllers.count == 1 ? NO : YES;
}
Copy the code

If you like, give a like or follow it