Showing a one-time UIViewController via presentModalViewController upon launch
Greetings! I have a working iPhone app (huzzah!) that uses a MainView.xib
containing a fully-stocked UITabBar with several UINavigationController objects and views at-the-ready.
I've now been asked to add a one-time registration view to this mix. This view would appear before the UITabBar at app-launch, get some info from the user, register with a server - or check for an existing registration, then squirrel some data away in the keychain. (If the keychain already shows proof of registration, then we skip showing this particular view.)
The registration and keychain part I've got under control (thank you Erica Sadun for the latter!), but showing that initial one-time view is proving to be trickier than I expected.
I suspect I'm too close to the problem to see what's wrong. I really hope it's pilot error and doesn't require anything too Rube Goldberg!
Here's the scenario:
The app starts by loading MainView.xib, in which lies the aforementioned UITabBar controller, et. al. For the sake of argument, let's say we must show that registration view. Also, we'd like it to have a modal appearance, so it will fly in from the bottom up. Then, when we're done, we can dismiss it, call a delegate (most likely the App Delegate) and tell it to carry on with the original UITabBar.
// Normally, the 开发者_运维技巧Tab Bar Controller's view is added to the window ... still do this?
[window addSubview:tabBarController.view];
// We could now set up a VC like so. Mostly harmless. (I know, "mvc" is an unfortunate abbreviation in this case.)
RegistrationVC *mvc = [[RegistrationVC alloc] initWithNibName:@"RegistrationView" bundle:nil];
Note that RegistrationView.xib
has a UIView inside, but no nav controller. We want to keep it decoupled so that it can be reused, say, as part of a tab bar item's nav controller (to review your registration info, for instance).
Moving on. We create a nav controller with the intent of presenting things modally:
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:mvc];
We then present our modal VC, using the tab bar controller as the basis, and release the alloc'ed bits.
[tabBarController presentModalViewController:nc animated:YES];
[nc release];
[mvc release];
First observation. Something tells me this is just plain sloppy. You can see the first tab bar item's nav bar and view appear just as the modal view swoops in. Yeccch! Moreover, trying to set the selected VC to nil beforehand has no effect:
tabBarController.selectedViewController = nil;
We really don't want/need to use the tab bar until after the modal VC is done (and we have the delegate to help let us know when that happens).
Why am I even bothering with the Tab Bar? Well, it looks like I need something to hang that modal VC's hat on, and I don't know what else there is to use.
Is this the only way? It just seems to tether the Registration VC and the Tab Bar unnecessarily, and it just smells ... wrong.
Clues welcome/appreciated!
It's hard to answer this without knowing what your Default.png shows. Assuming you're following the HIG and it displays an empty tabBarController, I'd suggest a somewhat complicated layering: bottom view: tabBarController.view middle view: UIImageView: Default.png top view: registration view positioned below the bottom of the screen
On startup, if you need to show the registration view, manually animate it upward, and once the animation is done remove the UIImageView below it. When registration is complete, manually animate the registration view downward to reveal the tabBarController. If on startup you don't need the registration view, just animate the UIImageView to fade away (or just remove it).
OTOH hand, if you're not following the HIG and instead showing some kind of splash screen, things get a bit easier. Layer like this: bottom view: tabBarController.view top view: UIImageView: Default.png
If you need to show registration, do presentModalViewController with animated:NO and then fade out the UIImageView. If not, just fade out the UIImageView.
That's a lengthy explanation w/o pictures, hope it makes sense. The salient point is that I'm suggesting adding a UIImageView:Default.png to be the first thing that is seen when the app starts, and use that to guide your transition into registration or tabBarController as appropriate.
精彩评论