본문 바로가기

Software/iOS & Objective-C

iPhone 개발 듀토리얼 - Window and view

Window and View

windowlayers

 
 vc


UIWindow

Window는 UIWindow 클래스로 구현되어 있다. iPhone 애플리케이션은 구동시에 UIWindow 객체를 생성하여 사용자에게 화면을 보여주게 된다.
Window-Based 애플리케이션으로 프로젝트를 생성하여 코드를 살펴보면, UIWindow 클래스의 인스턴스를 생성하는 부분이 없다. 인터페이스 빌더의 MainWindow.xib 파일에서 UIWindow 인스턴스가 정의되어 있기 때문에 따로 생성하지 않아도 아울렛이나 델리게이트를 통해 사용이 가능하다.

인터페이스 빌더를 사용하지 않고, UIWindow 를 생성하려면 UIApplication의 딜리게이터의applicationDidFinishLaunching 메소드에 다음과 같은 코드를 추가하여야 할 것입니다.(initWithFrame 메시지를 보내어 화면 크기만큼의 크기로 생성합니다.)

  1. UIWindow* aWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

UIWindow의 인스턴스를 생성하였으면, 이제 Window 에 View를 추가할 차례입니다.

  1. UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
  2. [view setBackgroundColor:[UIColor redColor]];
  3. [window addSubview:view];

 위의 코드를 수행하면 빨간 화면의 View가 Window에 추가되어서 보여지게 됩니다. 코드를 살펴보면, UIWindow와 같이 initWithFrame 으로 생성하는데 mainScreen이 아닌 applicationFrame 로 생성을 합니다. 이렇게 생성하면, statusBar 와 같은 Window 프로퍼티로 인한 크기를 제외한 실제 보여지는 화면 크기만큼으로 생성을 하게 됩니다.

 

UIView

UIView 는 iPhone 애플리케이션 구조에서 MVC 모델 중 View 역할을 담당하고 아래와 같은 일들을 처리합니다.

  1. 화면을 그리거나 애니메이션 효과를 연출
  2. 레이아웃을 구성하거나 서브뷰들을 관리
  3. 터치 이벤트를 처리

 

단순히 iPhone SDK 에서 제공해주는 컨트롤들을 사용하여 애플리케이션을 구성한다면, 인터페이스 빌더를 이용하여 UIView 에 원하는 컨트롤을 추가하고, 아울렛을 연결하는 정도 만으로도 충분히 구현가능합니다.

하지만, 복잡한 UI 구성이나 퍼포먼스 개선을 위해서는 iPhone 애플리케이션의 드로잉 메카니즘을 이해하고 적절히 구현하여야 합니다.

 

iPhone 애플리케이션이 화면을 구성하는 Drawing Cycle 을 살펴보도록 하겠습니다.

UIView 객체가 화면 업데이트 요청을 받으면 UIView 객체는 drawRect: 메소드를 호출합니다.

이 때 인자로 갱신해야할 영역이 CGRect 구조체를 참고하여 해당 영역을 업데이트 합니다.

drawRect: 메소드는 다음과 같은 경우에 호출 되어집니다.

  1. 비활성화 영역이 생겼을 때
  2. UIView 의 hidden 프로퍼티가 YES에서 NO로 토글 되었을 때
  3. 스크롤에 의해 화면에 보여질 영역이 변경 되었을 때
  4. UIView 의 setNeedsDisplay: 메소드와 setNeedsDisplayInRect: 메소드가 호출 되었을 때

이런 경우에 drawRect: 메소드가 호출되므로 커스텀 뷰를 개발 할때에는 drawRect: 메소드를 호출 하는 횟수를 줄이고 내용을 최소화하여 퍼포먼스를 개선해야 합니다.

개선 방법은 iPhone SDK 문서에 상세히 써있으므로 생략합니다.

 

다음으로 iPhone 애플리케이션의 주 이벤트인 터치 이벤트 처리를 살펴보도록 하겠습니다. 터치 이벤트는 크게 4종류로 전달 됩니다.

  1. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    : 화면에 터치가 발생하였을 때에 발생
  2. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    : 화면에 터치가 발생한 상태에서 이동하였을 때에 발생
  3. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    : 터치가 떨어졌을 때에 발생
  4. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    : 터치 이벤트가 시스템에 의해 취소되었을 때 발생 (예를들면 전화가 왔을때)

event

A multi-touch sequence and touch phases (출처 : iPhone Application Programming Guide)

 

터치이벤트는 touches 인자로 전달되며, NSSet 형태로 전달되어 싱글터치 및 멀티터치 처리가 가능합니다.

(싱글터치가 아닌 멀티터치를 처리하려면 multipleTouchEnabled 프로퍼티를 YES로 설정하거나, isMultipleTouchEnabled 메소드를 오버라이드 하여 YES 를 return 해주면 처리가 가능합니다.)

4가지의 이벤트는 Responder 에게 전달되며, 전달 규칙은 Responder Chain 에 의해서 전달 됩니다. 일반적으로는 UIView 가 이벤트를 가장 먼저 받게 됩니다.(First Responder)

Responder가 터치 이벤트를 처리하지 않았을때는, Next Responder 에게 이벤트를 보냅니다. UIView 경우에는 super view 에게 해당 이벤트를 보냅니다.

이런식으로 체인이 이루어지고 최종적으로 UIWindow가 이 이벤트를 받게되고, UIWindow는UIApplication으로 이벤트를 보냅니다. 이와같은 방식은 Chain of Responsibility 패턴을 참고하시기바랍니다.

반응형

'Software > iOS & Objective-C' 카테고리의 다른 글

멀티스레딩 <NSThread>  (0) 2011.12.30
메모리 관리 <Objective-C?>  (0) 2011.12.29
Xcode & Objective-C - 기초개념 1.  (0) 2011.09.19
네트워크 in iPhone & iPad  (0) 2011.09.17
해킨토시 설치 삽질중...  (0) 2011.09.16