Hidden back button appears sometimes in navigation bar

background, ios, uisplitviewcontroller

Solution

It appears to be an issue when setting the `hidesBackButton` property during view controller transitions (For which `viewWillAppear` is a part of that process). I didn't notice this issue in iOS6, so I believe it's to do with the way iOS7 handles transitions and rendering.

The solution for me was ensuring the `hidesBackButton` had the correct state at initialization. So you'll need to set the property value within `- (id)init`, or some variation thereof.

If this isn't possible, then the best I could do was set the state in `viewDidAppear` instead of `viewWillAppear`, ensuring it's animated so it's not too jarring for the user.

For example:

[self.navigationItem setHidesBackButton:YES animated:YES];

Problem

In my application, I'm using Split view with back button hidden in detail view controller and also I'm doing some background operations. Sometimes when app comes from background to foreground after doing background operations the hidden back button appears on the navigation bar. This happens only when we come to foreground after done with background operations, and it doesn't appeared if we come to foreground and still the background operation is in progress. I don't understand why the hidden back button appears some times even though I hide that. If I tap on that button nothing happens but it still appears. Please help me to solve this issue. In the RootView of Right Panel, I'm hiding the back button like this ``` - (void) viewWillAppear { self.navigationController.navigationItem.hidesBackButton = YES; self.navigationController.navigationItem.leftBarButtonItem = nil; } ``` In didEnterBackground, started background task with a timer ``` UIApplication* app = [UIApplication sharedApplication]; backgroundTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:backgroundTask]; backgroundTask = UIBackgroundTaskInvalid; }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:INITIAL_BACKGROUND_TIME_LIMIT target:self selector:@selector(pushPullServer) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode]; [[NSRunLoop currentRunLoop] run]; }); ``` After coming from background, In appDidBecomeActive ``` - (void) appDidBecomeActive { self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.tabBar, detailNavigation, nil]; self.splitViewController.delegate = self; self.window.rootViewController = self.splitViewController; } ```

Original source