views:

4598

answers:

7

When starting the app, if the user doesn't have login information stored, I want to display a modal view controller to force the entry of this information. I found through trial and error, that this had to occur in viewDidAppear of my root view controller. I tried to put it in viewDidLoad and viewWillAppear, but those didn't work unless I assigned the view of the root view controller to the view of the navigation controller used in the modal which then caused other issues...

So I have:

- (void)viewDidAppear:(BOOL)animated
{
     NewAccountViewController *newAccountViewController = [[[NewAccountViewController alloc] initWithNibName:@"NewAccountViewController" bundle:nil] autorelease];

     UINavigationController *accountNavigationController = [[UINavigationController alloc] initWithRootViewController:newAccountViewController];
  [self presentModalViewController:accountNavigationController animated:YES];  
}

And in the newAccountViewController I have a simple navigation item button that dismisses the modal view controller with dismissModalViewController.

This all works and when the modal is dismissed a view in a navigation controller is visible with its navigation item title at the top....

But there is a white gap about the same size as the status bar between the status bar and the top of the blue navigation item bar. If I don't do the modal, then the gap is never there. It only occurs after the modal is presented and dismissed. I've tried doing animated:NO on both the present and dismissModalViewController. I've also tried not using the navigation controller in the modal, and that did nothing as well. Any ideas would be great! Thanks.

A: 

OK, I do not know why this happens, it happened to me though and ill tell you how i fixed it. I found that adding a view at 0,0 made it overlap with the status bar...this is weird because before 3.0 I never had projects do this behavior 0,0 was always underneath the status bar. Anyway so I saw that it was overlapping so i started putting my views at 0,20 or however big the status bar is. That was cool until I tried using a modal view controller, when it dismissed i found the gap the size of the status bar (what you are expiriencing), for some reason the modal view thinks 0,0 DOES NOT overlap the status bar and when it dismisses 0,20 (of your previous view) shows up as if (0,0) does not over lap and (0,20) has the extra white gap. Why did this start happening ? No clue. Anyway to fix it i knew i had to fix the whole overlap of the view and status bar at 0,0 thing. I kept trying but nothing, then I decided to try to create a new View based project in xcode (which sets up the initial view for you) and see if their view overlaps (or if they put it at 0,20), what i found is that it DID NOT overlap and 0,0 was the right placing, right below the status bar and not overlapping it. Bizzare? i think so. So what i did on my project was copy the set up they had in the newly created view based project (they set the viewControllers property through Interface Builder, you can create a view based project like I did and just mimic their set up), i found that this fixed the issue, views at 0,0 no longer overlapped the status bar and dismissing modal view controllers no longer left the gap. Dont know if this is your case, but it might be, hopefully this will help you.

Daniel
I'm not creating any of my views through code. I am simply doing initWithNibName... on all my view controllers to load their views, I'm still new at this. I just found that I have the same behavior if I add a tab controller. I have commented out the modal behavior, but now when my app loads, it loads the first view in a nav controller inside a tab controller, and the gap is at the top of the page. I'm not sure if this affects this, but inside methods like viewDidLoad when I create the tab controller or nav controller, I am setting the current vc's view, to that of the tab or nav controller.
Brian
not too sure of what you are doing, in your nibs are the views at 0,0?
Daniel
I think I fixed it, but I'm not sure why. Layout - Root VC creates TabBar Controller and adds Prefs View Controller to it. Also sets self.view = tabBarController.view. Prefs View Controller, creates a Nav Controller and adds Users View Controller to the Nav Controller. Also calls [self.view addSubview:navigationController.view]; This works. I'm not sure if I know when to use addSubView vs. self.view = x.view. If in my root, I do addSubview, then I get the space. In my Prefs VC, if I do self.view = x.view then I get the space. Do you have any advice. Thanks for your help.
Brian
What I said in the above comment worked for my issue with navigation controllers inside of a tab bar, but not the modal view controller. I used the hiding the status bar method which works.
Brian
generally you shouldnt do self.view=x.view when you want to switch views, from another viewcontroller, you should either do addSubview or presentModalView. You shouldnt be doing self.view = tabBarController.view u should do either self.view a ddSubview or self pushModalview
Daniel
+2  A: 

I ran into the same issue. Not sure what causes it, but I fixed it with the following line of code just after I dismiss my modal view:

[self.view setFrame:CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height)];

Just adjust the Y offset to meet your needs. In another instance I had to make it 20 instead of 10.

Mark Hammonds
This is hackerish, this issue is annoying as hell and only started occuring after 3.0, i wonder whats cuasing it
Daniel
It does a bit hackerish, bit this is the only one that worked for me. Thanks Mark :)
Tudorizer
+4  A: 

I had the same problem. My solution was to temporarily close the status bar just before switching views:

- (void) temporarilyHideStatusBar {
  [[UIApplication sharedApplication] setStatusBarHidden:YES];
  [self performSelector:@selector(showStatusBar) withObject:nil afterDelay:0];
}
- (void) showStatusBar {
  [[UIApplication sharedApplication] setStatusBarHidden:NO];
}

// Use these by calling the hide function just before a broken view switch:
[self temporarilyHideStatusBar];
[self doViewSwitch];

// No need to call [self showStatusBar]; explicitly.

I experimented with other code-based solutions, and I like this one the best because it works 100% of the time - some of my frame-based solutions only worked most of the time - and because it has minimal user-visible effects.

I suspect this is an Apple bug, and it would be nice to hear the official word from them on the best workaround.

Tyler
I found that this worked in some cases, and doesn't work in others. When I wouldn't have the issue with the same modal view controller, when the modal view controller closes, it would push the underlying navigation controller underneath the status bar. To fix this issue, I have my tab bar controller present the modal view controller instead of the view controller that created the tab bar controller.
Brian
Interesting ... I think Brian's suggestion makes sense. I am going to see if that applies to my implementation.
mobibob
+4  A: 

Turns out this was happening because I was calling my modalviewcontroller on the current view controller, but my view controller already had a another view controller loaded as a subview. Once I changed it to make the view controller in the subview, load the modal, then it went away. Thanks for all your help.

Brian
A: 

I am running into the same problem. I admit that I may have taken a nontraditional route, embedding a tab bar in a NavController, and now I'm kinda seeing why they say not to do it. Well, whatever, it makes sense for my app, even if it is a total pain to implement.

My problem is that once I pushed a Modal VC onto a TabController subview (which is, in turn, a subview of the overarching NavController View, which has control of the top NavBar... which turns into a delegation nightmare) and then dismiss the MVC, the view that comes back is pushed up under the NavBar. Doesn't happen when I add or push any other subviews, just with MVCs.

[self.view setFrame:(CGRect)] does seem to do the trick, if I call it right after [self dismissModal...]. However, it has to be called on all subviews of my tab bar controller, or even the other lists are shunted up under the bar. Poopy.

Makes things a headache, but not unsolvable. But I agree, this is a new bug with 3.x (or maybe it's one of those double-edged "new features"), and it's downright annoying. I'm downloading 3.1.2 SDK now, and hopefully it addresses this. Gonna comment my [setFrame] lines and see what happens. But hopefully, if it's not solved in this version, it will be soon. Until then, it seems that the solution is a lot of (admittedly hackerish and repetitive) code.

EDIT: Nope, updating didn't help. Poop. Back to the code I go, to hard-define the position of every screen. Awesome. Hopefully the size of Nav and Tab Bars doesn't ever change.

EDIT 2: Hey! I solved it! (i R prowd.) Seems the problem was that, when my MVC was dismissed, my view got passed back to the tab bar controller, which had "forgotten" it had a nav bar above it. Don't tell me how, I'm probably way out of documented territory by now. But, I solved my particular problem by simply redefining the [subview.view setFrame:0,0,width, height] after returning from editing. Not sure why this made any difference, but in the app it did, because no longer is the first one and a half rows of my table view sneaking up under the nav bar. So I really have no advice, just find the right place to put

[(appropriateViewController).view setFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height];

Not sure why it works but it does. Isn't that the worst kind of error?

jimiHendrix
I have done the same set frame to itself's frame and it fixed the problem. I have been advised not to do that and to check if I have any added subviews that are not set to support 'autosizing.' This problem still rages on in my work.
mobibob
did you consider using a toolbar instead of the tab bar? Sometimes that is what one is doing with a tab bar and it might be easier to manage. (Just thinking out loud.)
mobibob
+1  A: 

I had the exact same problem... my solution? Manually set the height of the view you're displaying modally to 480 px in interface builder.

Problem solved.

Steve
+1  A: 

Just wanted to chime and say I had the exact opposite problem - a white gap at the bottom of the screen. And the fix was also the opposite, I was presenting from a subview, when I needed to be presenting from the parent. Thanks!

nomad00