I\'ve got an iPhone application with a UITableView
menu. When a row in the table is selected, the appropriate view controller is pushed onto the application\'s
I had the same problem and here is the solution that worked for me. Say you're pushing SomeUIViewController
onto your navigation stack.
Define this (private) ivar in the interface of SomeUIViewController
:
// keep a reference to the navigation controller for use in viewDidDisappear:(BOOL)animated method
UINavigationController * _navigationController;
Implement the following methods of SomeUIViewController
:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// here, your controller still has a reference to self.navigationController
_navigationController = [self.navigationController retain];
}
- (void)viewDidDisappear:(BOOL)animated {
// at this point, self.navigationController = 0x0, so
// use your retained reference to the navigation controller to perform any last minute operations, then release
[_navigationController setToolbarHidden:YES];
[_navigationController release];
[super viewDidDisappear:animated];
}
The idea is that you want to hide the toolbar owned by the navigation controller after SomeUIViewController
's view has disappeared. This way, you avoid any unwanted display artifacts.
DISCLAIMER
This is merely an answer that shows a workaround solution for the stated question. It is meant solely to point out a detail of the inner workings of the framework. It is also meant as an example of what not to submit to the Apple AppStore.
Try implementing a UINavigationControllerDelegate and setting it to your navigation controller's delegate property. This achieved for me what you are describing in your post, with no visible artifacts.
The following code assumes that secondController is pushed into the navigation view by an action performed in the firstController.
MyNavigationControllerDelegate.h
@interface MyNavigationControllerDelegate : NSObject<UINavigationControllerDelegate> {
}
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
@end
MyNavigationControllerDelegate.m
#import "MyNavigationControllerDelegate.h"
#import "AppDelegate_Shared.h"
@implementation MyNavigationControllerDelegate
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([AppDelegate_Shared sharedDelegate].firstController == viewController ) {
[navigationController setNavigationBarHidden:TRUE];
[navigationController setToolbarHidden:FALSE];
}
}
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([AppDelegate_Shared sharedDelegate].secondController == viewController ) {
[navigationController setNavigationBarHidden:FALSE];
[navigationController setToolbarHidden:TRUE];
}
}
@end
sharedDelegate is just a helper method:
AppDelegate_Shared.m
+ (AppDelegate_Shared*)sharedDelegate {
return (AppDelegate_Shared*)[[UIApplication sharedApplication] delegate];
}
This is just a wild stab in the dark but maybe you should let the runloop run once after hiding the toolbar:
[viewController setToolbarHidden:YES animated:YES];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]];
For the UIViewController that does not need a toolbar when pushed you can consider using either
Implementing the hidesBottomBarWhenPushed method for that UIViewController:
// method to be added to the UIViewController that has no toolbar
- (BOOL) hidesBottomBarWhenPushed {
return YES;
}
Or prior to pushing in the UIViewController, set the value of hidesBottomBarWhenPushed:
viewControllerWithNoToolBar.hidesBottomBarWhenPushed = YES
[self.navigationController pushViewController:viewControllerWithNoToolBar animated:YES];
I too have experienced this problem. In my case, the only way I found to successfully hide the toolbar without showing the background of the window is to call [self.navigationController setToolbarHidden:YES animated:animated]
in your view controller’s -viewDidAppear:
method.