뷰간의 애니메이션 전환을 위해서는 아래와 같은 방식을 해야 한다.

View transition

If you want to change the appearance of a view during a transition—for example, flip from one view to another—then use a container view, an instance ofUIView, as follows:

  1. Begin an animation block.

  2. Set the transition on the container view.

  3. Remove the subview from the container view.

  4. Add the new subview to the container view.

  5. Commit the animation block.


중요한 것은 두 view 간의 전환을 담당하는 컨테이너 뷰 (부모 뷰?)를 두어야 하는 것이다.
( 그렇게 하지 않고 뷰1번이 뷰2번 전환을 담당하게 만들면 애니메이션이 안되고 그냥 확 바뀐다. ; )


프로젝트는 Window based로 생성한다.


1. FirstViewController, SecondViewController 마련하기

File/ New Files로 간 후
Cocoa touch class 중
UIViewController subclass로 FirstViewController를 생성
UIViewController subclass로 SecondViewController를 생성

File/ New Files에서
User interface 중
View XIB로 FirstView로 생성
View XIB로 SecondView를 생성


2. FirstView, SecondView Xib 설정하기
 
FirstView.xib를 더블 클릭하여 Interface Builder를 띄운 후
FirstView.xib의 File's owner를 선택한 후 Tools/ Inspector를 연다.
인스펙터의 4번째 탭의 Class identifier를 선택한 후 FirstViewController를 선택한다.


그리고 File's Owner를 오른클릭한 후 View를 First.xib안의 View로 드래그 드럽으로 연결한다.

그리고 마지막으로 Label을 이용하여 First를 붙인다.

이를 마찬가지로 Second.xib에 대해서도 동일하게 적용한다.


3. RootViewController 마련하기

File/ New Files로 간 후
Cocoa touch class 중
UIViewController subclass로 RootViewController를 생성

RootViewController.h

#import <UIKit/UIKit.h>



@interface RootViewController : UIViewController {

IBOutlet UIButton *button1;

}


- (IBAction) OnFlipView;


@end



RootViewController.m

#import "RootViewController.h"


#import "FirstViewController.h"

#import "SecondViewController.h"


// 간편하게 하기 위해 두 뷰 컨트롤러 포인터를 전역 변수로 마련하였다.


FirstViewController* g_FirstViewController = nil;

SecondViewController* g_SecondViewController = nil;



@implementation RootViewController


...


// Implement viewDidLoad to do additional setup after loading the view.

- (void)viewDidLoad {

    [super viewDidLoad];


// 두 뷰 컨트롤러를 생성한다.

// Xib의 이름을 넣는다. (이때 대소문자 맞춰야한다. xib를 FIrstView로 해서;; 아래처럼 소스를 짰다. )


g_FirstViewController = [[FirstViewController alloc] initWithNibName:@"FIrstView" bundle:nil];

g_SecondViewController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];



// RootViewController의 뷰에 자식 뷰로 g_FirstViewConroller의 뷰를 추가한다. 이 때 button1 자식뷰와 FirstView는 형제 뷰이지만 button1 자식뷰가 firstview보다 앞에 나오게 되어 보이게 된다. (ms윈도우의 z-order과 동일 개념)

// 버튼도 뷰다. UIButton의 클래스 상속을 올라가보면 UIView에서 시작하고 있다.



[self.view insertSubview:g_FirstViewController.view belowSubview:button1];

}



...


// 루트 뷰의 버튼을 누르면 동작되는 뷰전환 함수


- (IBAction) OnFlipView 

{

    UIViewController *from;

UIViewController *to;



// 루트 뷰 자식(sub) 뷰로 firstview 또는 secondview 중 둘 중 하나만 달라 붙도록 코딩되어 있다.

// 만일 g_FirstViewController.view의 부모뷰(superview)가 있다면 현재 firstview가 붙어 있으므로 firstview에서 secondview로 전환되도록 한다.



if( g_FirstViewController.view.superview != nil )

{

from = g_FirstViewController;

to = g_SecondViewController;

}

else

{

from = g_SecondViewController;

to = g_FirstViewController;

}



// 애니메이션 블럭 시작

    [UIView beginAnimations:nil context:NULL];

    [UIView setAnimationDuration:1];

    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];


[to viewWillAppear:YES];

    [from viewWillDisappear:YES];



// 이전 뷰를 부모 뷰(rootview)에서 떼어낸다.

[from.view removeFromSuperview];

// 루트 뷰에다가 전환될 뷰를 추가한다.

[self.view addSubview:to.view];

// 전환될 뷰의 위치는 루트 뷰에 있는 button1과 형제 뷰로써 존재하지만 버튼 보단 뒤에 있게 된다.

[self.view insertSubview:to.view belowSubview:button1];

[from viewDidDisappear:YES];

[to viewDidAppear:YES];


    [UIView commitAnimations];

}


@end




루트 뷰를 메인 윈도우에 추가하기 위해서 다음 처럼 한다.
AppDelegate에 IBOutlet으로 추가해야 나중에 MainWindow.xib의  File's Owner에 root가 보이게 된다.

FlipViewAppDelegate.h

#import <UIKit/UIKit.h>


@class RootViewController;



@interface FlipViewAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

IBOutlet RootViewController* root;

}


@property (nonatomic, retain) IBOutlet UIWindow *window;


@end


FlipViewAppDelegate.m

#import "FlipViewAppDelegate.h"

#import "RootViewController.h"


@implementation FlipViewAppDelegate


@synthesize window;



- (void)applicationDidFinishLaunching:(UIApplication *)application {    


    // Override point for customization after application launch

     // main window에 자식 뷰로 root뷰를 추가한다.

[window addSubview: [root view]];

    [window makeKeyAndVisible];

}



- (void)dealloc {

[root release];

    [window release];

    [super dealloc];

}



@end



RootView를 위해서는 따로 xib를 만들지 않고 그냥 MainWindow.xib안에 추가하도록 하겠다.

먼저 라이브러리에서 ViewController를 MainWindow.xib에 추가한다.



그리고 View Controller를 선태한 후 Tools/ Inspector에서 네번째 탭의 Class 를 RootViewController로 선택한다.
그리고 버튼도 하나 가져다 놓는다.


Root View Controller를 오른클릭하여 버튼과 Outlet 연결을 한다.
버튼은 button1과 연결
OnFlipView도 버튼과 연결한 후 Touch Down과 연결한다.


마지막으로 Flip View App...를 오른클릭 한 후 root를 Root View Controller로 연결한다.



4. 실행하기

cmd + R를 하여 실행하여 버튼을 누르면 First View에서 Second 뷰로, 또 버튼 누르면 Second에서 First로 계속 바뀌게 된다.




정리

- 뷰들 간에는 자식 뷰, 부모 뷰 이렇게 계층을 나눌 수 있다. 
- 뷰들은 투명하다. 즉 부모 뷰와 자식뷰가 있고 자식뷰가 부모 뷰 전체를 덮고 있더라도
  부모 뷰의 컨트롤 (여기 예제에서는 버튼)과 자식 뷰의 컨트롤 (여기 예에선 라벨)이 동시에 보이게 된다.

+ Recent posts