-->

Show a view as a splash screen in didFinishLaunchi

2020-07-25 07:45发布

问题:

I have a Tab Bar Application and I want to simply display a view (splash screen) once the didFinishLaunchingWithOptions method loads up the tab bar controller. Why is this so hard? Please show me how I'd load up and show a Xib file called SplashView.xib below and display it:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // Add the tab bar controller's view to the window and display.
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];

    // Load up and show splash screen Xib here

    return YES;
}

回答1:

First thing I'd mention is that splash screens are specifically frowned upon in the HIG. Especially ones that only serve to make the user wait & stare at some logo they don't care about.

Now that rant is out of the way, I'll assume that you probably have some loading going on that you'd like to have happen before the tabs are displayed.

In this case I don't load up a tab bar in the MainWindow.xib. Instead I launch my single view (with XIB) that does the loading. The reason is this: You'll pay for the loading of all of those views before you can even see your splash screen.

In the case of loading data, sometimes these tabs depend on this data being loaded, so it makes more sense to wait to load up the tab bar controller.

The app delegate ends up looking like this:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [window makeKeyAndVisible];
    [window addSubview:splashController.view];  //this assumes MainWindow.xib defines your splash screen, otherwise....

    UIViewController *splashController = [[SplashController alloc] initWithNibName:@"SplashController" bundle:nil];
    splashController.delegate = self;
    [window addSubview:splashController.view];

    //hang on to it in an ivar, remember to release in the dealloc
}

Then in the splash screen controller, when I'm done loading, I do this:

-(void)doneLoading {
    [self.delegate performSelector:@selector(splashScreenDidFinishLoading)];
}

Of course self.delegate doesn't exist, and it can be added simply like this:

//header
@property (nonatomic, assign) id delegate;

//implementation
@synthesize delegate;

Then just make sure and implement that method on the app delegate:

-(void)splashScreenDidFinishLoading {
     //load up tab bar from nib & display on window
     //dispose of splash screen controller
}

I've used this pattern in a handful of apps and is simple and works well. You could also choose to do a nice transition animation in the method above.

Hope this helps.



回答2:

In your app delegate's header file:

@interface AppDelegate {
    ...
    IBOutlet UIView *splash; // add this line
}

In IB open the SplashView.xib, set the File Owner's class to the class of your app delegate, connect the splash outlet. Add this to show a splash view:

[[NSBundle mainBundle] loadNibNamed: @"SplashView" owner: self options: nil];
[window addSubview: splash];

You will possibly want to hide the splash view too:

[splash removeFromSuperview];
[splash release];
splash = nil;

You could use UIView animation block to fade out the splash view to be extra-cool. That said, splash screens are evil.

I think the app delegate is indeed a better place for this kind of stuff.



回答3:

I would do something like:

    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Splash.png"]];
    [imageView setCenter:CGPointMake(240, 160)];

    self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [self.view addSubview:imageView];

    [imageView retain];

    [NSTimer scheduledTimerWithTimeInterval:3.0 target:self //display for 3 secs
     selector:@selector(continueLoadingWhatever:)
     userInfo:nil
     repeats:NO];

And then...

- (void)continueLoadingWhatever:(id)sender {
    //do whatever comes after here
}

I probably wouldn't do this in the app delegate, but in the root view controller. You should never have to add anything unnecessary directly to the window, especially if it contains interaction (I know this doesn't).