Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

io7 navigation check when finish transition

I want to mark that my UINavigationController is animating (push/pop) or not.

I have a BOOL variable (_isAnimating), and the the code below seem work:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    _isAnimating = YES;
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    _isAnimating = NO;
}

But it work incorrectly in iOS7 with swipe gesture. Assume my navigation is: root-> view A -> view B . I'm currently on B.

  • In begin of swipe (go back from B to A), the funcion "navigationController:willShowViewController:animated:(BOOL)animated" is called, then _isAnimating = YES.

  • The normal case is the swipe is finished (go back to A), the function "navigationController:didShowViewController:animated:(BOOL)animated" is called, then _isAnimating = NO. This case is OK, but:

  • If the user may just swipe a half (half transition to A), then don't want to swipe to the previous view (view A), he go to the current view again (stay B again). Then the function "navigationController:didShowViewController:animated:(BOOL)animated" is not called, my variable has incorrect value (_isAnimating=YES).

I have no chance to update my variable in this abnormal case. Is there any way to update the state of navigation? Thank you!

like image 820
vietstone Avatar asked May 20 '14 08:05

vietstone


1 Answers

The clue to solve you problem can be found in the interactivePopGestureRecognizer property of UINavigationController. This is the recognizer which responds for popping controllers with a swipe gesture. You can notice that the state of the recognizer is changed to UIGestureRecognizerStateEnded when the user rises finger up. So, additionally to Navigation Controller delegate you should add target to the Pop Recognizer:

UIGestureRecognizer *popRecognizer = self.navigationController.interactivePopGestureRecognizer;
[popRecognizer addTarget:self                       
                  action:@selector(navigationControllerPopGestureRecognizerAction:)];

This action will be called each time the Pop Recognizer changed, including the end of a gesture.

- (void)navigationControllerPopGestureRecognizerAction:(UIGestureRecognizer *)sender
{
    switch (sender.state)
    {
        case UIGestureRecognizerStateEnded:

        // Next cases are added for relaibility
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateFailed:

            _isAnimating = NO;
            break;

        default:
            break;
    }
}

P.S. Do not forget that the interactivePopGestureRecognizer property is available since iOS 7!

like image 115
kelin Avatar answered Oct 19 '22 06:10

kelin