io7 navigation check when finish transition
Asked Answered
B

1

13

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!

Buckinghamshire answered 20/5, 2014 at 8:20 Comment(7)
Have you tried using the isBeingPresented property of UIViewController?Interdepartmental
Chào! Did you try viewWillAppear:?Reube
@Interdepartmental and Thanh-NhonNGUYEN isBeingPresented and viewWillAppear: is inside A or B. My code is not A or B, it's another class (it's delegate of UINavigationController, it's role is navigation manager). Beside, my code may have many view, there're A, B, C, D, ..... not only A and BBuckinghamshire
Why don't you just keep track of the variable in the viewWillAppear:(BOOL)animated and viewWillDisappear:(BOOL)animated methods of respective VCs? Add a delegate protocol and make the VCs conform to it. That should make your manager capable of receiving callbacks from the VCs if that's what you want.Augustineaugustinian
@camdaochemgio you got any solution. I'm running into the same issueIleostomy
@Ileostomy Have you resolved it? I had a solution for this. If you still stuck, we can talkBuckinghamshire
@camdaochemgio Could you add that solution as an answer? If you do it within 3 days, you will get the bounty of 50 rep.Autecology
F
4

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!

Farci answered 22/12, 2015 at 11:51 Comment(2)
I'm not very good with UINavigationControllers, how can I detect whether the first or the second view controller will be shown after the animation ended? I have tried using the navigationController property, but it is null inside the method. Also the state is not useful, it is always ended in my tests. Any idea how I can detect this?Autecology
What do you mean by "the first" and "the second' controllers? If you need to understand, whether the user has finished the gesture, or not, you can add a flag _swipeCompleted and set it to YES inside the didShowViewController method. You also may look at viewControllers property of the Navigation Controller, it always contain all controllers in the stack. And if you need to know which controller will be shown before the animation ends, use variable viewController which is passed to willShowViewController.Farci

© 2022 - 2024 — McMap. All rights reserved.