Better solution:
a) Get some sleep.
b) Realize that, while you were sleeping, the use of 'UIBarStyleBlackTranslucent' has been deprecated, so simply do this instead:
- Open MainWindow.xib in Interface Builder, select your 'UINavigationBar' item inside the 'Navigation Controller' inside your 'Tab Bar Controller' and change the 'Style' to 'Black Opaque' instead of translucent.
In your UITableViewController class file, write
- (void)viewWillDisappear:(BOOL)animated {
self.navigationController.navigationBar.translucent = YES; /* Yes, go underneath the Navigation Bar elsewhere if you want to. */
[super viewWillDisappear:animated];
}
- (void)viewWillAppear:(BOOL)animated {
self.navigationController.navigationBar.translucent = NO; /* No going underneath the Navigation Bar. Problem solved! */
...
[super viewWillAppear:animated];
}
c) Stop feeling embarrassed and instead realize how sleep is now one more useful coding technique in your arsenal. ;p
The clues to the correct solution:
"The navigation controller never displays content under an opaque navigation bar."
"Set the translucent property of your navigation controller to YES. This allows your content to underlap the navigation bar."
see: developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/NavigationControllers/NavigationControllers.html
see: developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationBar_Class/Reference/UINavigationBar.html#//apple_ref/occ/instp/UINavigationBar/translucent
UIBarStyle Defines the stylistic appearance of different types of views...
UIBarStyleBlackTranslucent = 2, // Deprecated
Use UIBarStyleBlack and set the translucent property to YES instead.
http://developer.apple.com/iphone/library/documentation/uikit/reference/UIKitDataTypesReference/Reference/reference.html
BEFORE SLEEPING, fixed it
"The Hard Way"...
- (void)correctFrame:(UIView *)viewWithWrongFrame {
CGRect correctedFrame = [[viewWithWrongFrame superview] frame];
correctedFrame.size.height = correctedFrame.size.height - self.navigationController.navigationBar.frame.size.height; /* Height without Navigation Bar */
correctedFrame.origin.y = correctedFrame.origin.y + self.navigationController.navigationBar.frame.size.height; /* Origin below Navigation Bar */
[viewWithWrongFrame setFrame:correctedFrame];
}
- (void)viewDidLoad {
[super viewDidLoad];
...
[self correctFrame:[self.navigationController.view.subviews objectAtIndex:0]]; /* Correct the frame so it is after the Navigation Bar */
[self.tableView setContentInset:UIEdgeInsetsMake(-self.navigationController.navigationBar.frame.size.height, 0, 0, 0)]; /* Eliminate initial blank space at top.*/
...
}
- (void)cleanDisplay {
[self.tableView setContentInset:UIEdgeInsetsZero]; /* Fix difference between horizontal and vertical orientation. */
...
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
[self correctFrame:[self.navigationController.view.subviews objectAtIndex:0]]; /* Correct the frame so it is after the Navigation Bar */
/* Clean the display after turning... */
[self performSelectorOnMainThread:@selector(cleanDisplay) withObject:nil waitUntilDone:NO];
}
- (void)viewWillAppear:(BOOL)animated {
...
[self performSelectorOnMainThread:@selector(cleanDisplay) withObject:nil waitUntilDone:NO];
...
}
Note that failed approaches included:
Using Interface Builder to embed the UITableView inside a UIView. Did not work because it all got automatically sized to the full height.
Resizing [self.tableView superview].frame = CGRectInset([self.tableView superview].frame, 44, 44);
or .bounds had no effect,
neither did self.tableView.frame nor .bounds.
The clue to what was wrong came when I tried:
self.navigationController.view.frame = CGRectInset(self.navigationController.view.frame, 20, 44);
which actually changed the size of the view with the table in it. Clearly, changing the subview to that would fix the original problem.
Fixed it with the approach further above. Although before moving back or forward to other screens changes need to be reverted to normal to avoid shifting elements elsewhere.