Skip to content
AnArcher edited this page Aug 5, 2011 · 5 revisions

Recipe 1 : Add a Basic Splash Screen Transition

Splash Screen Transition : a fade between the default image and initail UI.


  • PRPSplashScreen : UIViewController
    • custom splash image
    • -hide method that executes the fade.

@interface PRPSplashScreen : UIViewController {}
    @property (nonatomic, retain) UIImage *splashImage;
    @property (nonatomic, assign) BOOL showsStatusBarOnDismissal;
    @property (nonatomic, assign) IBOutlet id<PRPSplashScreenDelegate> delegate;
    - (void)hide;
@end


  • PRPSplashScreenDelegate
    • @protocol
    • PRPSplashScreen의 delegate(위임)이다.
      • delegate이 필요한 이유는 무엇일까?
    • Screen이 나타나거나, transition의 시작과 끝에 대한 이벤트에 대한 콜백 메소드들이 구현되어 있다.
    • @optional 으로 이 protocal을 구현이 모든 methods을 다 구현할 필요 없게 했다. (왜?)

@class PRPSplashScreen;

@protocol PRPSplashScreenDelegate 
@optional
- (void)splashScreenDidAppear:(PRPSplashScreen *)splashScreen;
- (void)splashScreenWillDisappear:(PRPSplashScreen *)splashScreen;
- (void)splashScreenDidDisappear:(PRPSplashScreen *)splashScreen;
@end

  • PRPSplashScreen -loadView
    • PRPSplashScreen의 -loadView 메소드에서 UIImageView을 만들어서 PRPSplashScreen.view으로 등록한다.

- (void)loadView {
    UIImageView *iv = [[UIImageView alloc] initWithImage:self.splashImage];
    iv.autoresizingMask = UIViewAutoresizingFlexibleWidth |
    UIViewAutoresizingFlexibleHeight;
    iv.contentMode = UIViewContentModeCenter;
    self.view = iv;
    [iv release];
}

  • PRPSplashScreen -splashImage

- (UIImage *)splashImage {
    if (splashImage == nil) {
        self.splashImage = [UIImage imageNamed:@"Default.png"];
    }
    return splashImage;
}

  • Setting up the splash screen
    • application의 root view controller의 modal view controller으로 PRPSplashScreen을 등록하면 된다.
    • PRPSplashScreen object은 XIB에 등록해서 연결한다.

// in AppDelegate_iPhone.h
...
#import "PRPSplashScreen.h"

...
@property (nonatomic, retain) IBOutlet PRPSplashScreen *splashScreen;


// in AppDelegate_iPhone.m

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self.window addSubview:self.navController.view];
    self.splashScreen.showsStatusBarOnDismissal = YES;
    self.splashScreen.modalTransitionStyle =
    UIModalTransitionStyleCrossDissolve;
    [self.navController presentModalViewController:splashScreen animated:NO];
    [self.window makeKeyAndVisible];
    return YES;
}

  • Begin the transition
    • PRPSplashScreen은 UIViewController이기 때문에, 기본적인 UIViewController 메세지(-viewDidAppear ...)를 전달 받는다.
    • splashScreenDidAppear의 selector을 만들어서,
    • PRPSplashScreen의 delegate에 이 selector을 받을수 있는지 확인후에,
    • delegate에 splashScreenDidAppear을 호출한다.
    • -hide을 호출한다.
      • 왜 performSelector: withObject: afterDelay:을 써야 하나? -hide하면 안될까?
        • UIKit이 viewDidAppear을 종료한 후에 처리하기 위해서?



- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    SEL didAppearSelector = @selector(splashScreenDidAppear:);
    if ([self.delegate respondsToSelector:didAppearSelector]) {
        [self.delegate splashScreenDidAppear:self];
    }
    [self performSelector:@selector(hide) withObject:nil afterDelay:0];
}



  • PRPSplashScreen -hide method

    • -dismissModalViewControllerAnimated: 사용.
    • UIStatusBar에 대한 처리
      • Info.plist에 (Status bar initaily hidden..) UIStatusshowsStatusBarOnDismissal을 YES으로 설정.


- (void)hide {
    if (self.showsStatusBarOnDismissal) {
        UIApplication *app = [UIApplication sharedApplication];
        [app setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
    }
    [self dismissModalViewControllerAnimated:YES];
}


  • PRPSplashScreenDelegate의 구현을 AppDelegate_iPhone,AppDelegate_iPad에서 한다.
    • transition이 끝나면(-viewDidDisappear: -> -splashScreenDidDisappear:) splashScreen을 제거하기 위해서. (그래서 @optional?)


# AppDelegate_iPhone.m
- (void)splashScreenDidDisappear:(PRPSplashScreen *)splashScreen {
self.splashScreen = nil;
}


  • For both of portrait and landscape modes.
    • UIViewController는 autorotation 기능이 있다.
    • PRPSplashScreen을 상속하여 PRPSplashScreen_iPad.m을 만든다.
    • 다른 PRPSplashScreen의 메소드는 변경하기 않고 위의 메소드만 추가.

- (BOOL)shouldAutorotateToInterfaceOrientation:
    (UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}


  • IPad에 다른 splash image
    • portrait,landscape 의 이미지를 제공할수 있고,UIKit이 알아서 맞는 이미지를 찾는다.
    • 하지만, 코드에서 어떤 이미지를 사용하는지 알기 쉽지 않다.
    • 그냥 AppDelegate_iPad에 다른 이미지를 넣자.

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self.window addSubview:self.splitViewController.view];
    UIImage *splash = [UIImage imageNamed:@"splash_background_ipad.png"];
    self.splashScreen.splashImage = splash;
    self.splashScreen.showsStatusBarOnDismissal = YES;
    self.splashScreen.modalTransitionStyle =
    UIModalTransitionStyleCrossDissolve;
    [self.splitViewController presentModalViewController:splashScreen animated:NO];
    [self.window makeKeyAndVisible];
    return YES;
}