Upload
wanbok-choi
View
2.913
Download
7
Embed Size (px)
DESCRIPTION
Citation preview
멀티뷰 애플리케이션
CHAPTER 06
목 차• 뷰 스위처 애플리케이션• 멀티뷰 애플리케이션의 구조
– 콘텐츠 뷰 해부• 뷰 스위처 만들기
– 뷰 컨트롤러와 nib 파일 만들기– 애플리케이션 델리게이트 수정하기– SwitchViewController.h– MainWindow.xib 고치기– SwitchViewController.m 작성하기– 콘텐츠 뷰 구현하기
• 전환 시 애니메이션 주기
Introduction
아이폰의 기본 애플리케이션 중 주식 애플리케이션은 두 개의 뷰를 가지는데 , 하나는 데이터를 보여주고 다른 하나로는 주식종목을 설정한다
전화 애플리케이션은 탭바를 사용하는 멀티뷰 애플리케이션의 한 예이다
메일 애플리케이션은 내비게이션 바를 사용하는 멀티뷰 애플리케이션의 예이다
아이팟 애플리케이션은 내비게이션 바와 탭바를 모두 사용한다
뷰 스위처 애플리케이션
뷰 스위처를 실행한 모습 뷰 바꾸기 (Switch View) 버튼 누른 후
가운데 버튼을 눌렀을 때 보여주는 경고창
멀티뷰 애플리케이션의 구조• 최상위 컨트롤러
– 애플리케이션이 실행되고 나서 사용자에게 최초로 보여지는 컨트롤러– UIViewController, UINavigationController 나 UITabBarCon-
troller 의 인스턴스가 최상위 컨트롤러로 사용– 최상위 컨트롤러는 2 개 이상의 뷰를 가지며 사용자의 입력에 알맞는
뷰를 보여주는 역할을 한다 .
• 멀티뷰 애플리케이션에서 화면의 대부분은 콘텐츠 뷰로 구성 – 각각의 콘텐츠 뷰는 아웃렛과 액션을 포함한 자신만의 컨트롤러를
가지고 있다– 일반적으로 각각의 콘텐츠 뷰들은 뷰 컨트롤러 , nib, UIView 의
하위클래스로 구성
뷰 스위처 만들기• 새 프로젝트 생성
– 프로젝트 이름 View Switcher, Window-based Application 옵션 선택
뷰 컨트롤러와 nib 파일 만들기• UIViewController subclass 를
선택하고 XIB for user interface 옵션을 제외
• 두개의 .xib 파일을 생성– BlueView.xib, YellowView.xib
애플리케이션 델리게이트 수정하기• View_SwitcherAppDelegate
.h#import <UIKit/UIKit.h>
@class SwitchViewController;
@interface View_SwitcherAppDelegate : NSObject <UIApplicationDele-gate> {
UIWindow *window;
SwitchViewController *switchViewController;
}
@property (nonatomic, retain) IBOut-let UIWindow *window;
@property (nonatomic, retain) IBOutlet SwitchViewController *switchViewController;
@end
• View_SwitcherAppDelegate.m
#import "View_SwitcherAppDelegate.h"
#import "SwitchViewController.h"
@implementation View_SwitcherAppDelegate
@synthesize window;
@synthesize switchViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after applica-tion launch
[window addSubview:switchViewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[window release];
[switchViewController release];
[super dealloc];
}
@end
SwitchViewController.h
• 필요한 아웃렛이나 액션을 추가해서 MainWindow.xib 에 SwitchViewController 를 추가#import <UIKit/UIKit.h>
@class BlueViewController;@class YellowViewController;
@interface SwitchViewController : UIViewController {YellowViewController *yellowViewController;BlueViewController *blueViewController;
}@property (retain, nonatomic) YellowViewController *yellowViewController;@property (retain, nonatomic) BlueViewController *blueViewController;
-(IBAction)switchViews:(id)sender;@end
MainWindow.xib 고치기• 새로 추가할 클래스는 UIViewController 의
하위클래스이므로 라이브러리에서 View Controller( 그림 ) 를 찾아서 nib 의 메인 창에 끌어놓는다 .
Drag
MainWindow.xib 고치기• nib 메인 윈도우의 뷰
컨트롤러 아이콘을 클릭하고 ⌘4 를 눌러 아이덴티티(identity) 인스펙터를 띄운다 .
• UIViewController 라고 되어 있는 Class 콤보박스를 클릭하고 클래스를 SwitchViewController 로 바꾼다 .
MainWindow.xib 고치기• 최상위 컨트롤러의 컨텐츠 뷰는 화면
하단에 배치될 툴바로 구성– 라이브러리에서 뷰를 끌어서 윈도우에
놓는다 .– 라이브러리에서 툴바를 집은 후 뷰의
바닥으로 끌어서 그림과 같이 만든다 .
• 툴바 버튼을 액션 메서드에 연결– Bar Button Item 의 속성
인스펙터를 연다 . (⌘1)– 버튼에서부터 Switch View 컨트롤러
아이콘으로 컨트롤을 누른 채로 끌어 놓고 switchViews: 액션을 고른다 .
SwitchViewController.m 작성하기#import "SwitchViewController.h"#import "BlueViewController.h"#import "YellowViewController.h“
@implementation SwitchViewController@synthesize yellowViewController;@synthesize blueViewController;
- (void)viewDidLoad{
BlueViewController *blueController = [[BlueViewController al-loc]
initWithNibName:@"BlueView" bundle:nil];self.blueViewController = blueController;[self.view insertSubview:blueController.view atIndex:0];[blueController release];[super viewDidLoad];
}- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil){
YellowViewController *yellowController =[[YellowViewController alloc] initWithNib-
Name:@"YellowView"bundle:nil];self.yellowViewController = yellowController;[yellowController release];
}[blueViewController.view removeFromSuperview];[self.view insertSubview:yellowViewController.view
atIndex:0];}
else{
if (self.blueViewController == nil){
BlueViewController *blueController =[[BlueViewController alloc]
initWithNibName:@"BlueView"bundle:nil];self.blueViewController = blueController;[blueController release];
}[yellowViewController.view removeFromSuperview];[self.view insertSubview:blueViewController.view
atIndex:0];}
}...- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview[super didReceiveMemoryWarning];// Release anything that's not essential, such as cached dataif (self.blueViewController.view.superview == nil)
self.blueViewController = nil;else
self.yellowViewController = nil;}
- (void)dealloc {[yellowViewController release];[blueViewController release];[super dealloc];
}@end
SwitchViewController.m 작성하기#import "SwitchViewController.h"#import "BlueViewController.h"#import "YellowViewController.h“
@implementation SwitchViewController@synthesize yellowViewController;@synthesize blueViewController;
- (void)viewDidLoad{
BlueViewController *blueController = [[BlueViewController al-loc]
initWithNibName:@"BlueView" bundle:nil];self.blueViewController = blueController;[self.view insertSubview:blueController.view atIndex:0];[blueController release];[super viewDidLoad];
}- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil){
YellowViewController *yellowController =[[YellowViewController alloc] initWithNib-
Name:@"YellowView"bundle:nil];self.yellowViewController = yellowController;[yellowController release];
}[blueViewController.view removeFromSuperview];[self.view insertSubview:yellowViewController.view
atIndex:0];}
else{
if (self.blueViewController == nil){
BlueViewController *blueController =[[BlueViewController alloc]
initWithNibName:@"BlueView"bundle:nil];self.blueViewController = blueController;[blueController release];
}[yellowViewController.view removeFromSuperview];[self.view insertSubview:blueViewController.view
atIndex:0];}
}...- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview[super didReceiveMemoryWarning];// Release anything that's not essential, such as cached dataif (self.blueViewController.view.superview == nil)
self.blueViewController = nil;else
self.yellowViewController = nil;}
- (void)dealloc {[yellowViewController release];[blueViewController release];[super dealloc];
}@end
• viewDidLoad 를 오버라이드해서 BlueViewController 의 인스턴스를 만듬• initWithNibName 메서드를 이용하여 BlueView.xib 파일에서 Blue-
ViewController 인스턴스를 로드• initWithNibName 에 넘기는 파일명에는 .xib 확장자가 없는 것에 주의• BlueViewController 의 인스턴스를 만들고 나서 blueViewController 의
프로퍼티로 할당한다• 다음으로 파란 뷰를 최상위뷰의 하위 뷰로 추가
• 추가할 때 인덱스를 0 으로 해서 아이폰이 파란 뷰를 다른 뷰의 뒤에 놓이게 한다 .
SwitchViewController.m 작성하기#import "SwitchViewController.h"#import "BlueViewController.h"#import "YellowViewController.h“
@implementation SwitchViewController@synthesize yellowViewController;@synthesize blueViewController;
- (void)viewDidLoad{
BlueViewController *blueController = [[BlueViewController al-loc]
initWithNibName:@"BlueView" bundle:nil];self.blueViewController = blueController;[self.view insertSubview:blueController.view atIndex:0];[blueController release];[super viewDidLoad];
}- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil){
YellowViewController *yellowController =[[YellowViewController alloc] initWithNib-
Name:@"YellowView"bundle:nil];self.yellowViewController = yellowController;[yellowController release];
}[blueViewController.view removeFromSuperview];[self.view insertSubview:yellowViewController.view
atIndex:0];}
else{
if (self.blueViewController == nil){
BlueViewController *blueController =[[BlueViewController alloc]
initWithNibName:@"BlueView"bundle:nil];self.blueViewController = blueController;[blueController release];
}[yellowViewController.view removeFromSuperview];[self.view insertSubview:blueViewController.view
atIndex:0];}
}...- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview[super didReceiveMemoryWarning];// Release anything that's not essential, such as cached dataif (self.blueViewController.view.superview == nil)
self.blueViewController = nil;else
self.yellowViewController = nil;}
- (void)dealloc {[yellowViewController release];[blueViewController release];[super dealloc];
}@end
• 사용자가 노란 뷰를 처음 사용하게 될 때 로딩해야 한다 . - 지연 로딩 (lazy loading)
• If yellowViewController.view.superview == nil 이 YES 를 리턴하는 경우 .
• yellowViewController 가 존재하지만 뷰가 사용자에게 아직 보여지지 않았다면 그 뷰가 아직 뷰의 계층 구조에 속해 있지 않은 뷰여서 상위뷰를 가지지 않을 때
• yellowViewController 가 생성되지 않았거나 메모리에서 비워져서 yellowViewController 가 존재하지 않을 때
• nil 값을 리턴하는 경우• yellowViewController 의 인스턴스가 없기 때문에 새 인스턴스 하나를 생성해야 한다 .
• viewDidLoad 메서드에서 BlueViewController 를 생성했을 때와 같은 방법으로 Yel-lowViewController 의 인스턴스를 생성
• 그다음 뷰 계층에서 blueViewController 의 뷰를 삭제하고 yellowViewController 의 뷰를 추가
SwitchViewController.m 작성하기#import "SwitchViewController.h"#import "BlueViewController.h"#import "YellowViewController.h“
@implementation SwitchViewController@synthesize yellowViewController;@synthesize blueViewController;
- (void)viewDidLoad{
BlueViewController *blueController = [[BlueViewController al-loc]
initWithNibName:@"BlueView" bundle:nil];self.blueViewController = blueController;[self.view insertSubview:blueController.view atIndex:0];[blueController release];[super viewDidLoad];
}- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil){
YellowViewController *yellowController =[[YellowViewController alloc] initWithNib-
Name:@"YellowView"bundle:nil];self.yellowViewController = yellowController;[yellowController release];
}[blueViewController.view removeFromSuperview];[self.view insertSubview:yellowViewController.view
atIndex:0];}
else{
if (self.blueViewController == nil){
BlueViewController *blueController =[[BlueViewController alloc]
initWithNibName:@"BlueView"bundle:nil];self.blueViewController = blueController;[blueController release];
}[yellowViewController.view removeFromSuperview];[self.view insertSubview:blueViewController.view
atIndex:0];}
}...- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview[super didReceiveMemoryWarning];// Release anything that's not essential, such as cached dataif (self.blueViewController.view.superview == nil)
self.blueViewController = nil;else
self.yellowViewController = nil;}
- (void)dealloc {[yellowViewController release];[blueViewController release];[super dealloc];
}@end
• If yellowViewController.view.superview == nil 이 NO 를 리턴할 경우• blueViewController 를 가지고 동일한 과정을 진행
SwitchViewController.m 작성하기#import "SwitchViewController.h"#import "BlueViewController.h"#import "YellowViewController.h“
@implementation SwitchViewController@synthesize yellowViewController;@synthesize blueViewController;
- (void)viewDidLoad{
BlueViewController *blueController = [[BlueViewController al-loc]
initWithNibName:@"BlueView" bundle:nil];self.blueViewController = blueController;[self.view insertSubview:blueController.view atIndex:0];[blueController release];[super viewDidLoad];
}- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil){
YellowViewController *yellowController =[[YellowViewController alloc] initWithNib-
Name:@"YellowView"bundle:nil];self.yellowViewController = yellowController;[yellowController release];
}[blueViewController.view removeFromSuperview];[self.view insertSubview:yellowViewController.view
atIndex:0];}
else{
if (self.blueViewController == nil){
BlueViewController *blueController =[[BlueViewController alloc]
initWithNibName:@"BlueView"bundle:nil];self.blueViewController = blueController;[blueController release];
}[yellowViewController.view removeFromSuperview];[self.view insertSubview:blueViewController.view
atIndex:0];}
}...- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview[super didReceiveMemoryWarning];// Release anything that's not essential, such as cached dataif (self.blueViewController.view.superview == nil)
self.blueViewController = nil;else
self.yellowViewController = nil;}
- (void)dealloc {[yellowViewController release];[blueViewController release];[super dealloc];
}@end
• 현재 사용자에게 보여지고 있는 뷰가 어느 것인지를 확인하고 컨트롤러에 nil 을 할당하여 다른 뷰에서 참조할 수 없도록 컨트롤러를 해제• 컨트롤러는 뷰와 함께 메모리에서 제거 됨
콘텐츠 뷰 구현하기• BlueViewController.h
#import <UIKit/UIKit.h>@interface BlueViewController : UIViewController {}-(IBAction)blueButtonPressed;@end
• YellowViewController.h#import <UIKit/UIKit.h>@interface YellowViewController : UIViewController {}- (IBAction)yellowButtonPressed;@end
• BlueView.xib 를 더블클릭해 연다 .• File’s Owner 아이콘을 선택하고 ⌘4 를 눌러 아이덴티티 인스펙터를
띄운다 .• File’s Owner 의 기본값을 NSObject 에서 BlueViewController 로 바꾼다 .• 나머지는 책을 따라서 바꾸면 된다 .• YellowView.xib 역시 거의 같은 방법으로 바꾸면 된다 .
콘텐츠 뷰 구현하기• BlueViewController.m
#import "BlueViewController.h“
@implementation BlueViewController
- (IBAction)blueButtonPressed{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Blue View Button Pressed"message:@"You pressed the button on the
blue view"delegate:nilcancelButtonTitle:@"Yep, I did."otherButtonTitles:nil];[alert show];[alert release];
}
• YellowViewController.m#import "YellowViewController.h“
@implementation YellowViewController
-(IBAction)yellowButtonPressed{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Yellow View Button Pressed"message:@"You pressed the button on the
yellow view"delegate:nilcancelButtonTitle:@"Yep, I did."otherButtonTitles:nil];[alert show];[alert release];
}...
전환 시 애니메이션 주기• SwitchViewController.m 으로
돌아간다 .• switchViews: 메소드를 책에 있는
새로운 코드로 바꾼다 .• 아이폰에서는 다음 네 개의 뷰 트랜지션을
선택할 수 있다– UIViewAnimationTransitionFlipFrom-
Left– UIViewAnimationTransitionFlipFrom-
Right– UIViewAnimationTransitionCurlUp– UIViewAnimationTransitionCurlDown
전환 시 애니메이션 주기• 애니메이션을 진행하는 동안 뷰의 모습이 바뀌지 않으면 항상
캐시를 사용[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.view cache:YES];
• 트랜지션을 설정한 후 트랜지션할 때 사용하는 뷰별로 각각 한 번씩 메서드를 호출
[self.blueViewController viewWillAppear:YES];
[self.yellowViewController viewWillDisappear:YES];
• 뷰 바꾸기가 끝나면 이 뷰들에 대해 두 번의 호출을 더 한다 .[self.yellowViewController viewDidDisappear:YES];
[self.blueViewController viewDidAppear:YES];