1 Articles, Search for 'event handling'

  1. 2009/02/13 iPhone Development - Event Handling
iPhone/강좌2009/02/13 12:23
Event Handling

iPhone의 운영체제는 기본적으로 멀티 터치를 지원합니다. iPhone은 기존에 사용자가 이용하던 마우스나 키보드를 벗어나, 화면에 보이는 객체를 자유 자재로 선택하여 조작할 수 있는 환경을 제공합니다. 이러한 터치 이벤트는 다음과 같이 크게 3가지로 분류되어 view에서 메시지를 수신하여 처리할 수 있습니다.

* touchesBegan
prototype:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에 손가락을 대면 호출됩니다.

* touchesEnded
prototype:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에서 손가락을 떼면 호출됩니다.

* touchesMoved
prototype:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에 손가락을 대고 드래그 동작을 하면 호출됩니다.

iPhone에서위와 같은 이벤트가 호출되는 순서를 그림으로 나타내면 다음과 같습니다.

사용자 삽입 이미지

사용자가 손가락 1개를 화면에 터치 하였을 때 UITouchPhaseBegan, 즉 touchesBegan 메시지를 수신하고 또 다른 손가락이 터치 되었을 때 다시 한번 touchesBegan 메시지가 수신됩니다. 이 상태에서 손가락을 떼지 않고 확대/축소를 하기 위해 움직이면 UITouchPhaseMoved, 즉 touchesMoved 메시지가 수신되고 마지막으로 손가락을 떼면 UITouchPhaseEnded, 즉 touchesEnded 메시지가 수신됩니다.

각각의 이벤트는 1-touch와 n-touch 모두 동일하게 발생 되며, UIControl을 상속받아 구현된 UIButton이나 UISlider등의 컨트롤은 이미 이러한 터치 이벤트를 처리하고 있기 때문에 개발자가 기본적인 기능만을 이용한다면 위의 이벤트를 처리할 필요가 없습니다. 하지만, Safari나 Google map같이 페이지를 확대/축소 하거나 위/아래로 이동하기 위해서는 해당 view에서 터치 이벤트를 수신하여 처리하여야 합니다.

HAN
위와 같은 이벤트를 처리하기 위해서는 UIView 클래스를 상속받은 View 클래스를 생성하고 그 클래스 안에서 메시지를 받아서 처리하여야 합니다. 이러한 동작을 하는 프로젝트를 생성하는 방법은 다음과 같습니다.

1. "Xcode"를 실행한 뒤 새 프로젝트를 생성합니다.

2. 다음 그림과 같이 "New Project" 창에서 "Windows-Based Application"을 선택한 뒤 "Choose" 버튼을 누릅니다.

사용자 삽입 이미지


3. 이번엔 생성하고자 하는 프로젝트 이름을 입력합니다. 여기서는 "EventHandling" 이라는 이름으로 프로젝트를 생성하겠습니다.

사용자 삽입 이미지


4. 아래 그림은 "Windows-Based Application"으로 생성된 가장 기본적인 응용 프로그램의 모습입니다. 이 중 "MainWindow.xib" 파일은 View나 기타 화면에 관련된 리소스를 포함하고 있는 파일이며, 새로운 View 클래스를 생성하기 위해 이 파일을 더블클릭 하여 "Interface Builder"를 실행합니다.

사용자 삽입 이미지


5. 다음은 "Interface Builder"의 모습입니다. 새로운 View를 추가하기 위해 "Library" 도구 창의 "View"를 드래그 하여 "Window"창으로 드랍 합니다.

사용자 삽입 이미지


6. View 의 위치가 "Window"안에 꽉 차도록 적당히 레이아웃을 배치합니다.

사용자 삽입 이미지


7. 이번에는 새로 생성된 View에 label을 추가합니다. View와 마찬가지로 "Library" 도구 창의 "Label"을 드래그 하여 "Window" 창으로 드랍 합니다.

사용자 삽입 이미지


8. "Label"을 "Window" 창으로 드랍한 뒤의 모습입니다.

사용자 삽입 이미지


9. "Label"의 위치와 "Text"값을 통해 내용을 수정합니다. 또한 Baseline, Layout 등을 통해 정렬 상태를 변경할 수 있습니다.

사용자 삽입 이미지


10. 이번에는 실제 코드에 사용될 UIView 클래스를 상속받은 View를 생성하기 위해 View의 클래스 이름을 변경합니다. "Window"창의 View를 선택한 뒤 "MyUI View Identity" 도구 창(4번째 탭)의 "Class"에 생성하고자 하는 클래스 이름을 입력합니다. 여기서는 "MyUIView"를 입력하였습니다.

사용자 삽입 이미지


11. 이번에는 "Label"을 코드와 연결하기 위한 선언을 합니다. "MyUI View Identity" 도구 창(4번째 탭)에서 "Class Outlets"의 하단에 있는 "+" 버튼을 눌러 새로운 항목을 생성하고, 해당 항목의 "Outlet"을 지정합니다. 여기서는 "helloLabel"를 입력하였습니다. 또한 이 항목의 데이터 형을 "UILabel"로 지정하기 위해 오른쪽 "Type"에 "UILabel"이라고 입력합니다.

사용자 삽입 이미지


12. 여기까지 작업이 완료되었다면, label과 실제 UI 상의 객체와 매핑 하는 일이 남았습니다. "MyUI View Connections" 도구 창(2번째 탭)에서 "Outlets"에 있는 "helloLabel"의 오른쪽 원 가운데를 드래그 하여 "Window"창의 "Label" 객체에 드래그 합니다. 아래 그림과 같이 드래그 중에 매핑 될 객체의 정보가 간단히 툴팁으로 표시됩니다.

사용자 삽입 이미지


13. 모든 작업이 완료된 후의 모습입니다.

사용자 삽입 이미지


14. 지금까지 작업한 내용을 저장합니다.

사용자 삽입 이미지


15. 저장한 결과를 바탕으로 실제 클래스 파일을 생성하기 위해 "Window"창의 "View"를 선택한 후 메뉴의 "File"-"Write Class Files..."를 선택합니다.

사용자 삽입 이미지


16. 기본적으로 위에서 입력한 "MyUIView"가 표시됩니다. 만약 윗 단계에서 "View"를 선택하지 않으면 다른 클래스를 저장하는 창이 나옵니다.

사용자 삽입 이미지


17. 생성한 클래스를 현재 프로젝트에 추가할 것인지 선택합니다. 사용할 예정이기 때문에 체크한 뒤 "Add"를 눌러 추가합니다.

사용자 삽입 이미지


18. 모든 UI 작업이 끝났으므로 "Interface Builder"를 종료합니다.

사용자 삽입 이미지


19. 최종적으로 생성된 UI 코드 입니다.

사용자 삽입 이미지


위의 방법으로 생성된 코드를 이용하여 터치 이벤트를 핸들링 하는 예제를 작성하여 보겠습니다.

자동으로 생성된 클래스의 부모 클래스를 지정하기 위해 "MyUIView.h"에서 다음과 같이 주석처리 되어 있는 부분을 수정합니다. 또한, 이벤트 처리를 위한 함수를 추가합니다.

@interface MyUIView : /* Specify a superclass (eg: NSObject or NSView) */ {
IBOutlet UILabel *helloLabel;
}

@end


@interface MyUIView : UIView {
IBOutlet UILabel *helloLabel;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

@end


또한, 이벤트 핸들링을 수행하는 함수를 "MyUIView.m" 파일에 추가하고 각각의 함수를 채웁니다.

#import "MyUIView.h"

@implementation MyUIView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Began";
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Ended";
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Moved";
}

@end


위 코드에서는 각각의 이벤트가 발생하면 "helloLabel"의 Text를 바꿈으로써 알 수 있도록 하였습니다.
이제 코드를 컴파일 한 뒤 실행하면 터치/드래그 할 때마다 Label의 텍스트가 변경하는 것을 볼 수 있습니다.

여기에서 좀 더 확장하여 터치 후 드래그시 Label이 드래깅 되는 부분을 따라다니도록 수정 해보겠습니다. "touchesMoved" 함수를 수정하여 원하는 기능을 수행할 수 있습니다.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Moved";

UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self];

CGRect labelPosition = [helloLabel frame];

labelPosition.origin.x = currentTouchPosition.x;
labelPosition.origin.y = currentTouchPosition.y;

[helloLabel setFrame:labelPosition];
}


위와 같이 수정한 뒤 iPhone 에뮬레이터를 실행하면 드래그 할 때마다 Label의 위치가 변경되는 것을 볼 수 있습니다.



사용자 삽입 이미지

아래는 본 실습에 사용된 코드 입니다.


Posted by AccessDenied

Leave your greetings.