Gentlepeople, I'm a newbie to iPhone & Objective-C, coming from a long background of procedural language.
I'm attempting to emulate the functionality of the Whole Foods' recipe search. In that app, the screen has a NavigationBar at the top, a TabBar at the bottom, and a grouping of three buttons toward the top of the screen. Selecting a button presents a slide-up screen from the bottom, covering the TabBar. The slide-up screen contains a picker, and a 'Done' button. This is not a modal screen, as witnessed by the fact that you can select a different button from above, and the picker will dynamically change. Also, this isn't an Action Sheet.
In recreating this behavior, I used the Autoscroll project from the iPhone's ScrollViewSuite sample to present a non-modal slide-up screen. This worked well. I can dynamically change the picker in the slide-up screen by selecting different buttons.
Since I wanted the slide-up screen to cover the TabBar, I used a suggestion from http://osdir.com/ml/iPhoneSDKDevelopment/2009-01/msg00246.html. In short, increasing the tabBarController.view.frame height effectively makes the frame larger than the screen, and the TabBar (which is anchored to the bottom) is removed from the user's view. The combination of the slide-up screen and hiding the TabBar was acceptable. Life was relatively rosy. All I needed to do was add the NavigationBar.
But when I changed the screen in IB from a View Controller to make it a Navigaion Controller screen, I somehow introduced a 20 pixel shift in the view when hiding the TabBar!? The NavigationBar itself is fine, but everything else underneath it shifts up by 20 pixels. (The slide-up screen is still fine, however.) (20 pixels is the height of the iPhone's status bar.)
My IB is the standard arrangement, having a MainWindow.xib with the TabBarCongroller, and the NavigationControllers within that.
Here is the code:
- (void)toggleThumbView
{
if (!thumbViewShowing)
{
[self createSlideUpViewIfNecessary]; // no-op if slideUpView has already been created
//Hide the TabBar, which introduces a 20 pixel shift up of everything except the navigation bar
UITabBar *ntoTabBar = self.tabBarController.tabBar;
CGRect tbcFrame = self.tabBarController.view.frame;
self.tabBarController.view.frame = CGRectMake(tbcFrame.origin.x ,
tbcFrame.origin.y ,
tbcFrame.size.width ,
tbcFrame.size.height + ntoTabBar.frame.size.height);
//The following code really doesn't matter for discussions about the problem, simply resizing the
//tabBarController.view.frame above has already introduced the 20 pixel problem
CGRect frame = [slideUpView frame];
frame.origin.y -= frame.size.height ;
frame.origin.y += ntoTabBar.frame.size.height ;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[slideUpView setFrame:frame];
[UIView commitAnimations];
thumbViewShowing = !thumbViewShowing;
}
}
I've tried playing with the autoresizingMask and the autoResizesSubviews. The following eliminates the 20 pixel shift:
[self.tabBarController.view setAutoresizesSubviews:NO];
Unfortunately it also keeps the TabBar from being hidden. Thinking the 20 pixels might be the clue, I've experimented with unchecking the IB 'Wants Full Screen' on all of the XIB's, but to no avail. I've checked & unchecked the resize from NIB, and I've removed all of the Simulated Interface Elements so that the program should have control of the resizing (I believe having those simulated prohibits the program control?) Again, nothing seems to be doing the trick. Increasing the tbcFrame.origin.y by 20 pixels eliminates the screen shift, but causes the NavigationBar to be lowered by 20 pixels, covering anything below and leaving a lovely 20 pixel margin at the top. The problem appeared in the 3.0 SDK simulator, and I upgraded to the 3.1.2. Nice to have the latest/greatest, but it didn't solve my problem.
I'd pull my hair out if I wasn't already bald. Any suggestions on where to look would be greatly appreciated. Would it be better to push the slide-up view via a separate ViewController and eliminate the programatic hiding of the TabBar? Something like:
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.hidesBottomBarWhenPushed = YES;
[[self navigationController] pushViewController:dvc animated:YES];
[dvc release];
Thank you in advance,
Bob B.