uchicago-mobi / 2015-Winter-Forum

8 stars 1 forks source link

Tips for Splash Screen #149

Closed tabinks closed 9 years ago

tabinks commented 9 years ago

In iOS8, the detail view controller is the default view presented on the screen regardless if its "compacted" on iPhone or on iPad. Even this baffled me a bit and was not obvious from the documentation. This means that it will always be visible on screen when the app launches.

One approach to take with the splash screen is as follows:

You can accomplish this with something like this:

// in DetailViewController.h
- (void)viewWillAppear:(BOOL)animated
{
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor greenColor];
    [self presentViewController:vc animated:NO completion:^{
        NSLog(@"Splash screen is showing");
    }];
}

This will result in a new green view controller being the first one the user would 'see' onscreen, despite it being loaded later in the launch cycle. There are many other ways to accomplish the splash screen effect, this is just one of them.

You will have to figure out how to dismiss it once the data is done loading. Hint: Create a custom protocol to allow your MasterViewController to send messages (assuming you are downloading here) to the DetailViewController.

bobby-digital-23 commented 9 years ago

Thank you for this - extremely helpful! 👍

narvemp commented 9 years ago

Thanks! This helps a lot.

emondai commented 9 years ago

I tried the code above but I get the following warnings: -Presenting view controllers on detached view controllers is discouraged -Unbalanced calls to begin/end appearance transitions for <UISplitViewController: 0x7f9d12a08e20>.

Any ideas on why this is happening? The first warning can be fixed by using self.parentViewController but I am not sure how to fix the second one.

narvemp commented 9 years ago

I'm having the same warnings. Also, with regards to using a protocol to pass messages between the Master and Detail, there seems to be a race condition where the master finishes downloading the data before the splash screen loads so the delegate call to dismiss the splash screen is missed by the detail view controller.

To fix this, I tried adding another protocol so the data would only begin downloading after the splash screen has loaded but this causes issues when trying to do something like masterviewcontroller.delegate = self. Putting the delegate setters in the AppDelegate isn't working either and is throwing an invalid selector error.

tabinks commented 9 years ago

NSNotificationCenter...Have you splash screen listen for a broadcast from your masterviewcontroller.

tabinks commented 9 years ago

In my implementation, I did not receive the warning. This is part of the fun/torture of iOS development...figuring out these little details.

JRam13 commented 9 years ago

Another way of doing this is setting your splashscreen as your rootviewcontroller (is initial view controller). Then calling your split view whenever you're done with that.

Nope. Don't do this. This should be done for a real splash/loading screen when the app loads, not what is intended for the assignment. Disregard.

narvemp commented 9 years ago

Thanks, I had tried NSNotificationCenter and revisited doing it that way. Turns out I hadn't used @selector() properly. -.-

susanstevens commented 9 years ago

My splash screen seems to be working fine on the simulator with iPad, but when I try it on iPhone 5, the master view controller loads first. It's only when I tap on an article in a tableview cell and switch over to the detail view controller that the splash screen loads. And then it's stuck on the splash screen, since the notification from the master view controller (that the data has loaded) has already come and gone unobserved.

I have my splash screen implemented as described above (in the detail view controller's viewWillAppear method)... Should I be checking which device the app is loading on, and then deciding whether to load the splash screen in the master or the detail? Or is there a better way of doing this?

narvemp commented 9 years ago

You shouldn't have to check the device. You can use multiple NSNotifications to make sure that the splash screen runs before you download the feed data, and then dismiss the splash screen after you download the data.

ceruzzi commented 9 years ago

Just to clarify. After the Splash Screen fades away, we should see the master view controller present automatically(in profile orientation)?

hwealnegn commented 9 years ago

I'm implementing the splash screen in the detail view's viewWillAppear, but the notification observer I set up to detect when the data has finished loading seems to receive the notification before the splash screen is ever displayed. I've tried putting my observer both in viewWillAppear and viewDidAppear but run into the same issue either way. I've also tried adding a conditional so that the notification would be observed only after the splash screen is loaded, but it seems like the conditional is also checked before the splash screen is ever displayed. Am I putting my observer in the wrong place?