iOS navigation issue: after pushing a ViewController, it results in a navigation bar showing the navigation items of the previous ViewController

StackOverflow https://stackoverflow.com/questions/21330676

Question

This situation happens very rarely and I don't know how to reproduce it, but it does happen sometimes and I would like to fix it.

In ViewController A, if I push ViewController Bin, sometimes(not always) when ViewController B did appear, the navigation bar is showing the navigation bar items of ViewController A, not those of ViewController B. If I click on the back button, I cannot go back to ViewController A, getting stuck in ViewController B.

A UIBarButtonItem is added to the navigation items of ViewController A, and the navigation items of ViewController A will be updated in response to some events. Is it the reason that causes this issue?

Codes for pushing ViewController B

ViewControllerB* viewControllerB = [ViewControllerB new];
[self.navigationController pushViewController:viewControllerB animated:YES];

Codes for updating the navigation items in ViewController A

- (void)viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];

    if(NumberOfCalendarOperations == 0){
        [self showNavigatorBarButtons];
    }
    else{
        [self startRefreshAnimationOnUpdateButton];
    }
}



//This method is triggered through notification when the number of operations in   calendarOperationQueue is changed

-(void)calendarOperationQueueStateDidChange:(NSNotification*)notification{
    if(NumberOfCalendarOperations == 0){

        if (self.isShowActivityIndicator) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self showNavigatorBarButtons];
            });
        }
    }
    else{
        if (!self.isShowActivityIndicator) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self startRefreshAnimationOnUpdateButton];
            });
        }
    }
}

/** * Show the update button on the right of navigation bar */

-(void)showNavigatorBarButtons{
    self.isShowActivityIndicator = NO;
    UIBarButtonItem *updateButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"sync.png"] style:UIBarButtonItemStylePlain target:self action:@selector(updateButtonDidPress:)];
    [self.navigationItem setRightBarButtonItems:[NSArray arrayWithObjects:updateButton, nil]];}

/** * Start refresh animation on the update button */

-(void)startRefreshAnimationOnUpdateButton{

    if (self.navigationController.topViewController != self) {
        return;
    }
    self.isShowActivityIndicator = YES;

    UIView* updateButtonView = nil;

    for (UIView *subViewInNavigationBar in self.navigationController.navigationBar.subviews){

    NSString *subViewClassAsString = NSStringFromClass([subViewInNavigationBar class]);

        if ([subViewClassAsString compare:@"UINavigationButton" /* TODO: be careful with this */
                              options:NSCaseInsensitiveSearch] == NSOrderedSame){

        if ([subViewInNavigationBar isKindOfClass:[UIView class]] == YES){

                if(updateButtonView == nil){
                    updateButtonView = subViewInNavigationBar;
                }
                else if(subViewInNavigationBar.center.x < updateButtonView.center.x){
                    updateButtonView = subViewInNavigationBar;
                }

        }

        }

    }

    for (UIView *subViewsInButton in updateButtonView.subviews){

        if ([subViewsInButton isKindOfClass:[UIImageView class]] == YES &&
            subViewsInButton.frame.origin.x != 0.0f &&
            subViewsInButton.frame.origin.y != 0.0f){

            [subViewsInButton removeFromSuperview];


            CGRect activityIndicatorFrame = self.updateButtonActivityIndicator.frame;
            activityIndicatorFrame.origin.x = (CGRectGetWidth(updateButtonView.frame) / 2.0f) - (CGRectGetWidth(activityIndicatorFrame) / 2.0f);
            activityIndicatorFrame.origin.y = (CGRectGetHeight(updateButtonView.frame) / 2.0f) - (CGRectGetHeight(activityIndicatorFrame) / 2.0f);
            self.updateButtonActivityIndicator.frame = activityIndicatorFrame;

            [self.updateButtonActivityIndicator startAnimating];

            [updateButtonView addSubview:self.updateButtonActivityIndicator];

            return;

        }

    }

}

Anyone has got a clue? Thank you.

Was it helpful?

Solution

Finally I found the reason of this issue. It is that I try to hide the navigation bar in viewWillDisappear. Now iOS allows me to back to the previous view by panning from the left edge of the screen. But while panning from the left edge, if I cancel this action, and pan back to the left edge, the navigation bar will enter this strange state.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top