높은 수준에 오른다면, iPhone Apps 개발과정은 같은 개발 툴과 같은 기본 라이브러리를 사용하기 때문에 Mac OS X apps를 만드는 제작 과정과 흡사 합니다. 그러나! 이러한 유사성이 있음에도 분명히 둘 사이에는 다른 점이 있습니다. 그 이유는 iPhone은 일반 데스크 탑과 다른 목적을 띄고 있고, (기본적으로 모바일 디바이스이며 전화기라는 점)매우 다른 디자인적 특성을 가지고 있기 때문입니다.
또한 아이폰과 아이패드, 아이팟의 터치스크린의 제한적 사이즈를 고려하여 정말로 유저가 필요한 정보들을 어떻게 잘 정돈할 것인가에 집중하여 디자인 하여야 할 것입니다.
iOS는 유저가 데스크탑 어플리케이션에서는 할 수 없는 작업(interact)들을 아이폰, 아이팟, 아이패드를 통해 구현할 수 있도록 지원해 줍니다. 예를들어 멀티 터치 인터페이스는 여러 손가락을 이용한 인식작용과 복잡한 입력을 쉽게 할 수 있도록 도와줍니다. 또한 accelerometers와 같은 하드웨어 탑재 기능은 비록 몇몇 데스크탑 시스템이 탑재 하고 있긴 하지만 iOS상에서 더욱 확장적으로 사용될 수 있습니다. 이러한 iOS만의 특수한 기능들을 잘 이해함으로써 유저를 위해 적절한 기능들을 활용함으로서 더욱 좋은 apps를 만들 수 있을 것 입니다.
다음은 MoveMe라는 샘플 어플리케이션을 통해 앞서 말한 기능들을 둘러 보도록 하겠습니다. MoveMe어플은 아이폰 어플에서 전형적으로 사용되는 다음과 같은 기능들을 보여줄 것입니다.
- 어플 시작하기
- 윈도우 보여주기
- 커스텀 콘텐츠 그리기
- 터치 이벤트 처리
- 애니메이션 활용
Figure 1은 MoveMe 어플의 인터페이스 입니다. Welcome버튼을 터치하면 버튼을 진동하고 손가락 가운데 위치로 버튼을 옮겨오는 애니메이션을 작동시킵니다. 손가락을 스크린 위에서 드래그 하면 버튼은 손가락을 따라오게 됩니다. 손가락을 스크린에서 떼면 또다른 애니매이션을 이용하여 버튼은 원래의 자리로 돌아가게 됩니다. 버튼의 바깥 쪽을 더블 텝핑 하게 되면 버튼의 인삿말이 다른 나라의 언어로 바뀌게 됩니다.
Figure1 The MoveMe application window

MoveMe의 샘플 코드를 다운 받으시려면
클릭! 하세요 (apple 공식 샘플 코드입니다.)
만약 Objective-C에 익숙하지 않으신분이라면 이전 포스팅인 Object-C 배우기: 초급 을 읽어보세요.
MoveMe 샘플 프로젝트를 해부해 보자!!다운받은 MoveMe 샘플 코드는 어플리케이션을 만들고 실행하기위한 서포트 파일과 소스코드들을 제공합니다.
MoveMe.xcodeproj 파일을 Xcode로 열게 되면 다음과 같은 화면을 보실수 있습니다.
Building the MoveMe Application!!
무브미 어플을 빌드하고 시뮬레이터에서 돌리기 위해 다음의 단계를 따라하세요.
1. MoveMe.xcodeproj 파일을 Xcode에서 여세요.
2. 프로젝트 툴바에서 Actice SDK 메뉴에 있는 simulator 옵션이 선택되었는지 확인하세요. (Active SDK 매뉴가 툴바에 나타나지 않으면 Project > Set Active SDK > Simulator.의 경로를 사용하세요)
3. Build > Build 에서 Go 를 선택하세요. 혹은 그냥 툴바에서 build와 go 버튼을 누르세요.
어플리케이션 빌딩이 끝나면 Xcode는 iOS Simulator에서 파일을 로드하고 실행시킬 것 입니다. 마우스를 이용하여 Welcome 버튼을 클릭하고 드래그하시면서 어플이 어떻게 작동하는지 확인 할 수 있습니다. 만약 사용할수 있는 디바이스가 있다면 디바이스 상에서도 확인하실 수 있습니다. 그 방법은
iOS Development Guide를 참조 하세요
A Word About Memory Management!!
iOS는 기본적으로 객체지향 시스템입니다. 그럼으로 대부분의 우리가 할당하는 메모리는 Object-C 오브젝트의 폼 안에 있습니다. iOS는 오브젝트에 의해 점유되는 메모리가 자유로이 쓸수 있도록 안전한지 알기 위해 reference counting schem을 사용합니다. 처음으로 오프젝트를 생성시킬때 그것은 레퍼런스 카운트를 1증가 시킵니다. 클라이언트는 오브젝트를 유지할수 있는지를 확인하는데서 부터 시작합니다. 만약 클라이언트가 오브젝트를 유지한다면 클라이언트는 그것이 더이상 필요하지 않을때 반듯이 릴리즈 해야 합니다. 오브젝트를 릴리징 하는것은 그것의 레퍼런스 카운트를 1 감소 시킵니다. 오프젝트의 레퍼런스 카운트가 0이 되었을때 시스템은 자동적으로 오브젝트의 메모리를 환원합니다.
** iOS는 Mac OS X v10.5 이상에서의 특징인 가비지 컬렉션을 사용하는 메모리 관리를 지원하지 않습니다. **
만약 오브젝트와 연관이 없는 메머리의 제네릭 블럭들을 할당하고 싶다면 기본 malloc 라이브러리를 불러와 사용할 수 있습니다. malloc을 사용하는 어떠한 메모리 할당의 경우 최후에는 개발자기 직접 free 라고 불리는 기능을 이용하여 메모리를 릴리즈 시켜주어야 할 의무가 있습니다.
개발자가 어떻게 메모리를 할당하던지 간에 메모리 관리를 overall하는 것은 중요합니다. 비록 iOS가 가상 메모리 시스템을 가지고 있지만 그것은 swap 파일을 사용하지 않습니다. (Swap file이란? 컴퓨터의 실제 메모리, 즉 램의 가상메모리 확장으로 사용되는 하드디스크상의 한 공간이다. 스왑파일을 가짐으로써, 컴퓨터 운영체계는 실제보다 더 많은 량의 램을 가지고 있는 것 처럼 동작할 수 있다. 즉 가장 오랫동안 저장되었던 램상의 파일이 새로운 파일을 위하여 하드디스크에 스왑파일로서 저장되었다 필요에 의해 불려지는 것이다. 페이징 이라고도 불림.) 이 말인 즉 코드페이지는 필요에 의해 가득 채워 질 수 있지만 동시에, 어플리케이션의 데이타는 반드시 메모리에 맞아 떨어져야 한다는 말이다. (여분이 없으니 메모리 관리를 잘하라는 말..;;). 시스템은 메모리의 여유공간을 모니터 하고 있다가 어플이 필요로 하는 메모리를 제공한다. 만약 메모리가 너무 치명적으로 터프해 지면 시스템은 어플을 그냥 닫아 버리게 된다. 하지만 이러한 옵션은 최후의 수단에만 사용이 된다(메모리가 딸려서 전화를 못받는 상황이 된다던지 하는..).
iOS에서의 오브젝트 할당에 대해 더 알고 싶다면
Cocoa Funamental Guide 를 참조 하자.
Initializing the MoveMe Application!!모든 C 기반의 프로그램들이 그렇듯이 모든 아이폰 어플들은 main이라고 불리는 펑션으로부터 시작된다. 좋은 소식중 한가지는 Xcode의 템플릿으로 새로운 프로젝트를 시작하게 된다면 개발자가 직접 작성하지 않아도 이부분이 자동 작성되어져 있다(감사감사 ㅠ).
다음은 MoveMe의 main 함수를 보여준다. main 함수는 프로젝트의 main.m 파일에 위치하고 있다. 모든 어플들은 main펑션을 가지고 있으며 거의 이것과 동일한 모습을 하고 잇다. 이 함수는 두가지 중요한 일을 수행한다. 첫째. 앞서 설명한 메모리 매니지먼트 레퍼런스 카운팅 시스템을 사용함으로서 어플리케이션의 탑레벨 오토 릴리즈를 생성한다. 즉 레퍼런스 카운트를 1로 만들어 주어 필요한 메모리를 할당 받는다. 둘째. MoveMe 어플의 중요한 오브젝트를 생성하기 위해 UIApplicationMain펑션을 불러온다. 그리고 이벤트 프로세싱을 반복한다. 어플리케이션은 이 함수를 프로그램을 종료할때까지 리턴시키지 않는다.
어플리케이션 델리게이트 정의!!개발되는 프로젝드의 가장 중요한 설계적 디테일중 하나는 프로젝트 안에서 개발자가 제공하는 클래스로부터 예시되어지는 어플리케이션 델리게이트 오브젝트를 정의 하는 것이다. MoveMe 프로젝트안의 어플리케이션 델리게이트 클래스는 MoveMeAppDelegate.h 안에서 그것의 인터페이스를 선언하고 MoveMeAppDelegate.m 파일 안에서 그것의 구현을 설명한다.
한번 이 파일들을 프로젝트에 첨가하면 개발자는 인터페이스 빌더를 사용하여 어플리케이션 델리게이트로서 클래스의 인스턴스를 디자인할 수 있다. 인터페이스 빌더는 개발자가 어플리케이션의 윈도우 안의 View를 창조하고 정비하며, View의 체계를 설립하며 각 View들의 옵션을 설정하고 각 뷰들의 관계를 지정할 수 있게 사용할 수 있는 시각적 Tool이다 .이것은 시각적 Tool이기 때문에 개발자는 이러한 모든 구성품들을 드래그함으로서 사용 할 수 있다. 그럼으로 단번에 인터페이스의 변화를 알아 볼수 있기 쉽게 한다. 인터페이스 빌더는 어플의 유저 인터페이스 (UI)를 nib 파일로 저장한다.
인터페이스 빌더를 실행하고 어플리케이션 델리게이트 오브젝트의 역할이 어떻게 정의 되었는지 보기 위해 Xcode 프로젝트 윈도우의 Groups & Files 블록에 있는 MainWindow.xib파일을 더블 클릭한다. MainWindow.xib는 어플리케이션의 윈도우를 포함하며 어플리케이션 델리게이트를 포함한 우리의 어플리케이션안의 몇몇 중요한 오브젝트들간의 관계를 지정하는 nib 파일이다. 어플리케이션 델리게이트의 관계가 어떻게 구성되어 졌는지 보기 위해서 File's Owner 아이콘을 클릭하고 inspector window 를 활성화 하며 Inspector window의 Application Coonections 탭을 클릭해야 한다. 다음은 Inpector 의 모습이며 File's Owner 오브젝트가 MoveMeAppDelegate 오브젝트로 연결된 델리게이트 아웃렛을 가지고 있는 것을 보여준다.
어플리케이션 델리게이트오브젝트는 어플리케이션 안에서의 조건변경에 응답하기 위해 기본 UIApplication 오브젝트와 협력하여 작동합니다. 어플리케이션 오브젝트는 거의 모든 막중한 일을 하지만 델리게이트는 다음과 같은 몇몇 주요 행동을 합니다.
- 어플리케이션의 윈도우와 초기 UI 셋업
- 커스텀 데이타 엔진을 위한 추가 시동 작업 작동
- 어플리케이션의 커스텀 URL 양식과 관련된 컨텐츠 열기
- 디바이스의 Orientation (?) 안에서의 변화에 응답 (이게 뭔말인가요?)
- 메모리 저용량 경고 처리
- 어플리케이션 종료를 위한 요청 시스템 처리
초기 구동시 델리게이트 오브젝트를 위한 거의 모든 주요 사항은 다음 장 "Creating the Application Window"에 묘사되어진 어플리케이션 윈도우를 셋업 하고 유저들에게 보여주는 것 입니다. 델리게이트는 또한 어떤 요구된 오브젝트를 창조하거나 (?) 이전의 상테로(Previous state)로 어플리케이션을 되살려 불러오기와 같은 즉시 사용 (Immediate use)을 위한 어플리케이션을 준비하기 위해 필요한 어떤 작업들을 수행하여야만 합니다. (어떤 요구된 오브젝트는 뭔말인지 모르겠지만 아무튼 어플을 키면 바로 이전에 사용하던 상태로 되살리거나 등등 키면 바로 켜져야 하는 작업등을 준비해야 한다는 말인듯 하네요.). 어플리케이션이 종료 될때 델리게이트는 어플리케이션을 순차적으로 셧다운 하는 작업을 할 필요가 있고 다음 실행 사이클에 필요한 상태 정보를 저장해야 합니다.
(예를 들어 오락을 하는데 끝판왕 앞에서 전화가 와서 어플이 꺼졌다면 통화후 다시 실행했을때 다시 일탄 부터 깨야 하는 걸 막는 다는 뜻. )
아이폰 어플의 라이프 사이클과 기본 설계구조에 대한 정보를 더 많이 얻기 위해선
"Core Application Architecture"와
iOS Application Programming Guide.를 참조 하세요.
Creating the Application Window!!모든 어플리케이션은 컨텐츠로 윈도우를 채우고 전체 화면을 다양히 채우는 윈도우를 창조해야할 책임이 있습니다. iOS에서의 그래픽적인 어플리케이션 구동은 다른 어플과 side-by-side로 구동되지 않습니다.(화면 분배, Picture in Picture같은걸 지원하지 않는 다는 뜻). 말인즉, 개발되는 어플리케이션은 절대로 하나이상의 UIWindow class의 인스턴스를 필요로 하지 않습니다.
윈도우들은 유저인터페이스에 필요한 드로잉 표면을 제공합니다. 하지만 view 오브젝트는 실제적인 컨텐츠를 제공합니다. view 오브젝트는 컨텐츠를 그리고 그 컨텐츠들과 상호작용하여 응답하는 UIView 클래스의 인스턴스입니다. iOS는 표, 버튼, 텍스트 필드 그리고 다른 타입의 인터렉티브 컨트롤들을 표현하기위해 스탠다드 view를 선언합니다. 개발자는 어플의 윈도우에 이런 view를 어떻게든 추가 할 수 있거나 UIView 서브클래스에 의해 정의된 커스텀 view를 선언하고 커스텀 드로윙과 이밴트 핸들링 코드를 구현할 수 있습니다. MoveMe 어플은 어플리케이션의 인터페이스를 보여주고 유저의 상호작용을 처리 하기 위해 두 종류의 view를 선언합니다; MoveMeView에 의해 구현되는 것과 PlacardView 클래스에 의해 구현되는 것.
어플리케이션 윈도우를 창조하고 시작 컨텐츠들을 가능한 빠르게 실현 시키는 것이 초기 실행의 목표 입니다. 윈도우는 MainWindow.xib nib파일로 부터 unarchived 입니다. 어플리케이션이 실행되고 이밴트 프로세스를 시작할 준비가 된 상태가 되면 UIApplication 오브젝트는 델리게이트를 applicationDidFinishLaunching 메세지로 보냅니다. 이 메세지는 컨텐츠를 어플의 윈도우에 넣고 어플이 요구하는 초기 실행 요소를 구현하기 위한 델리게이트의 큐 입니다.
MoveMe 어플에서, 델리게이트의 applicationDidFinishLaunching: 메소드는 다음과 같습니다.
1. 윈도우의 컨텐츠 뷰를 매니지 하는 일을 하는 view controller object를 창조 합니다.
2. 백그라운드 view와 전체 윈도우 프레임을 채우기 위해 moveMeView.xib nib 파일에 저장되어 있는 MoveMeView 클래스의 인스턴스로 view controller를 실행 시킵니다.
3. 윈도우의 서브 view로서 controller의 view를 추가 합니다.
4. 윈도우를 보여 줍니다.
다음의 코딩은 applicationDidFinishLaunching: 메소드이며 이것은 어플리케이션 델리게이트의 구현 파일인 MoveMeAppDelegate.m 을 선언합니다. 이 매소드는 윈도우를 위해 메인 컨텐츠 뷰를 창조하고 윈도우를 visible상태로 만들어 줍니다. 윈도우를 보여주는 것은 시스템이 어플리케이션이 이밴트 처리를 시작할 준비가 되었다는 것을 알려 줍니다.
**Note: 어플의 유저 인터 페이스를 셋업하는 것 이외에도 applicationDidFinishLaunching: 메소드를 사용 할 수 있습니다. 많은 어플리케이션들이 이것을 요구된 데이터 구조를 시작하고 유저 프리퍼런스를 읽거나 어플리케이션을 마지막 종료시의 상태로 리턴하기 위해 사용 합니다.
비록 이전의 코드가 윈도우의 백그라운드 view를 창조하고 윈도우를 보여준더라도 개발자가 이전의 코드에서 볼수 없는 것은 Welcome button을 나타내는 PlacardView클래스의 생성 이다. 이러한 행동은 MoveMeView오브젝트가 nib 파일로 부터 unarchived되었을때 initWithCoder: 매소드로 부터 불러지는 MoveMeView 클래스의 setUpPlacardView에 의해 처리 된다.
setUpPlacardView메소드는 다음의 코딩에서 보여 진다. 이 view는 PlacardView 오브젝트의 창조를 포함한다. MoveMeView 클래스는 전체 어플리케이션의 백그라운드를 제공하기 때문에 두개의 view의 관계는 Welcome 버튼을 어플리케이션 백그라운드의 탑에 보여줄 뿐 만 아니라 버튼에 연결되어진 이밴트를 MoveMeView클래스가 핸들링 할 수 있도록 허용 해 준다.
윈도우와 view생성에 관한 더 자세한 정보를 위해서는 "What Are Windows and Views?"를 참조하세요.
Drawing the Welcome Button!! 많은 타입의 간단한 컨텐츠를 그리기 위해서 별다른 변경 없이 UIKit에 의해 제공되는 기본 View를 사용 할 수 있습니다. (UIKit에 의해 제공되는 기본 컨텐츠들..버튼, 텍스트 레이블, 그래픽 뷰 등등..). 예를 들어 이미지 파일을 불러와 보여주기 위해서는 UIImageView 클래스를 사용할 수 있으며 Text 스트링을 보여 주기 위해서 UILabel 클래스를 사용 할 수 있습니다. MoveMeView클래스 또한 UIView 오브젝트로부터의 기본적인 프라퍼티를 사용 합니다(예를 들어 view를 솔리드 컬러로 채우기 위해 backgroundColor프라퍼티를 사용 했습니다. 이 프라퍼티는 view 오브젝트의 시작 매소드(initialization method) 안에서 코드로 설정 될 수 있습니다. 이러한 경우에 프라퍼티는 MoveMeView가 생성될때 MoveMeView.xib nib 파일안에 인터페이스 빌더의 인스펙터 윈도우의 Attributes tab에 컬러 well을 사용 하여 설정 됩니다. 하지만 개발자가 컨텐츠를 다이나믹 하게 그릴 경우, 개발자는 반듯이 UIKit안에 있는 더욱 진보된 드로윙 feature를 찾아 사용 해야 하거나 Quartz나 OpenGL ES등을 사용 해야 합니다. (UIKit에 있는 스텐다드 프라퍼티는 너무 단순해서 좀 더 고급스러운 이미지 구현을 위해선 다른 도구들을 사용 하는 것이 좋다는 말 입니다.)
MoveMe어플안에 있는 PlacardView 클래스는 Welcome 버튼을 그리고 스크린 위에서의 버튼의 위치를 관리 합니다. 비록 PlacardView클래스는 그것의 컨텐츠를 embedded UIImageView와 UILabel오브젝트를 사용해 그려 내지만, 그것은 전체적인 과정을 묘사하기 위해 컨텐츠를 명확하게 그려 냅니다.(구리지 않게 나름 괜찮다는 얘기인듯? ;;). 그 결과 이 클래스는 모든 커스톰 드로잉이 위치한 drawRect: 메소드를 view가 자리잡기 위해 구현합니다.
View의 drawRect: 메소드가 불러와 지는 동안 드로윙 환경은 실행을 준비 하기 위해 준비 되어 집니다. 개발자가 해야 할 일은 어떠한 커스텀 컨텐츠를 그리기 위한 드로윙 커맨드를 구체화 하는 일 입니다. PlacardView 클래스에서는, 컨텐츠는 리소스파일인 Placard.png로 저장되어 있는 백그라운드 이미지와 다이나믹 하게 변화될 수 있는 택스트 커스텀 스트링으로 구성 되어져 있습니다. 이 컨텐츠를 그리기 위해 클래스는 다음과 같은 과정을 밟습니다.
- view의 현재 경로에 백그라운드 이미지를 그립니다. (view는 이미 이미지에 맞도록 설정이 되어있기 때문에 이 과정은 전체 버튼 백그라운드를 제공합니다 .)
- welcome 스트링의 포지션을 계산하여 그것이 버튼의 중앙에 위치하도록 합니다. (스트링 사이즈는 변화 될 수 있기 때문에 포지션은 매번 현재 스트링 사이즈에 기반으로 하여 계산 되어 집니다.)
- 드로윙의 색깔을 검정으로 지정합니다.
- 스트링을 블랙으로 지정하고 약간 감쇄 (offset) 해 줍니다.
- 드로윙 컬러를 흰색으로 설정 해 줍니다.
- 스트링이 위치해야 할 장소에 흰색으로 다시 그려 냅니다.
다음은 PlacardView클래스를 위해 drawRect: 매소드를 보여 줍니다. PlacardImage 맴버 변수는 버튼을 위해 백그라운드 UIImage오브젝트를 가지고 있으며 currentDisplayString 맴버 변수는 Welcom 스트링을가지고 있는 NSString 오브젝트를 가지게 됩니다. 이미지를 그려낸 다음에 이 매소드는 view안의 스트링의 위치를 계산해 냅니다. 스트링의 사이즈는 스트링이 textSize맴버 변수에 저장되고 불러와질때 계산 되어져 이미 알고 있습니다. 스트링은 검은색, 흰색으로 NSString의 drawAtPoint:forWidthLwithFont:fontSize:lineBreakMode:BaselineAdjustment: 매소드를 이용해 두번 그려지게 됩니다.
좀 더 복잡한 이미지나 스트링을 표현해야 할 필요가 있다면 Quartz나 OpenGL ES를 사용 할 수 있습니다. Quartz는 벡터 기반의 Path와 이미지 그라디엔트, PDF그리도 다른 복잡한 컨텐츠를 그려내기 위해 UIKit과 함께 사용 됩니다. Quartz와 UIKit 은 같은 드로윙 환경을 기반으로 하기 때문에 view의 drawRect: 매소드로 부터 직접적으로 Quartz 함수를 불러올수 있으며 심지어 UIkit 클래스를 사용해 Quartz로 불러와 믹스 매치 하여 사용 할 수도 있습니다.
OpenGL ES는 2D와 3D 컨탵츠를 렌더할수 있게 해주는 Quartz와 UIKit의 대체 물이며 Mac OS X를 위한 OpenGL에서 찾을수 있는 함수들을 사용 할 수 있습니다. Quartz나 UIKit과 달리 drawRect:매소드를 드로윙에 사용 할 수 없습니다. view를 사용 할 수는 있지만 vuew 오브젝트를 OpneGL ES 코드의 표면에 드로윙을 제공하기 위해 주로 사용하게 됩니다. 표면 드로잉(Drawing Surface)를 얼마나 자주 업데이트 하고 어떤 오브젝트를 사용할지는 개발자의 결정에 달렸습니다.
더 자세한 정보를 얻기 위해선
iOS Application Programming Guide의 "Supporting High-Resolution Screen"을 참조 하세요.
Handling Touch Events!!iOS의 멀티 터치 인터페이스는 디바이스의 멀티플 핑거 터치에 의해 실행되는 이벤트를 인지하고 응답하며 구분 할 수 있게 해 줍니다. 멀티플 핑거에 대한 응답 능력은 가공할 만한 파워를 제공하면서 전통적인 마우스 베이스의 이벤트 핸들링 시스템 오퍼레이션의 전통적인 방식과 눈에 띄게 다르게 작동 합니다. 디바이스 표면의 각 손가락의 터치에 따라 터치센서가 새로운 터치 이벤트를 제공 합니다. 각 손가락이 움직임에 따라 손가락의 새로운 포지션을 인식하기 위해 추가적인 터치 이벤트가 제공되어 집니다. 디바이스 표면에서 손가락을 떼면 시스템을 그 사실을 인지하고 이벤트를 생성합니다.
시스템은 Swipe과 같은 일반적인 제스쳐를 인지 할수 있도록 제공해 주지만 개발자는 더 많은 복잡한 제스쳐를 인지 할 수 있도록 할 책임이 있습니다. 이벤트 시스템이 새로운 터치 이벤트를 가동 할때 그것은 각 손가락의 현재 위치에 대한 정보를 포함 합니다. 각 이벤트 오브젝트는 모든 터치 활동에 관한 정보를 수반 하고 있기 때문에 개발자는 시시각각 도착하는 각 이벤트의 정보로 부터 각 손가락의 활동들을 모니터 할 수 있습니다. 개발자는 어플리케이션에 적용할 컨텐츠에 적용할 제스쳐를 찾아내기 위해 이벤트에서 이벤트로 부터 각 손가락의 움직임을 추적할 수 잇습니다.
시스템은 이벤트를 UIResponder 클래스의 인스턴스인 어플리케이션의 응답 오브젝트로 보냅니다. 아이폰 어플에서 어플리케이션의 view는 개발자의 커스텀 리스폰터 오브젝트의 벌크로 형태를 가집니다. MoveMe 어플은 두개의 view클래스를 구현 합니다. 하지만 MoveMeView클래스만이 실질적으로 이벤트 메세지에 응답 합니다. 이 클래스는 다음과 같은 UIResponder 매소드에 오버라이딩 함으로서 Welcome 버튼의 안쪽, 바깥쪽 모두의 터치를 감지 합니다.
이것의 자체 이벤트 핸들링 행동을 단순화 하기 위해 MoveMe 어플리케이션은 오직 화면에 닿은 첫번째 손가락만을 추적합니다. 이것은 이런 일을 Multi-touch 이벤트를 초기화(Default) 하는 UIView 클래스의 도움으로 가능하게 합니다. 여러개의 손가락을 추적할 필요가 없는 어플리케이션은 이러한 기능이 매우 편리하게 이용 됩니다. 시퀀스 안의 추가적인 터치에 관련된 이벤트는 절대로 view로 전달 되지 않습니다. 만약 이러한 추가적인 정보를 얻기를 원한다면 (멀티 터치에 의한 다른 손가락의 위치와 행동에 관한 정보) UIView 클레스에 있는 setMultipleTouchEnabled: 매소드를 사용 함으로서 multi touch 서포트를 다시 활성화 할 수 있습니다.
이러한 이벤트 핸들링 활동의 일부로서 MoveMeView 클래스는 다음과 같은 과정을 수행 합니다.
- 첫번째 터치가 감지 되었을때 어디서 이벤트가 발생하였는지를 체크한다.
- Welcome 버튼의 바깥쪽의 더블텝은 버튼위의 String을 업데이트 한다.
- 버튼의 중앙 안쪽의 싱글텝은 버튼 확장의 에니매이션을 실행한다.
- 다른 모든 터치들은 무시 된다.
2. 만약 버튼의 안쪽에 있던 손가락이 움직이게 된다면 버튼의 포지션은 새로운 손가락의 위치에 맞추어져 업데이트 된다.
3. 만약 손가락이 버튼의 안쪽에 위치해 있었고 그것이 화면에서 떨어지게 된다면 애니메이션이 버튼을 원래의 위치로되돌린다.
다음은 MoveMeView클래스를 위한 touchesBegan:withEvent: 매소드 이다. 시스템은 첫번째 손가락이 기계에 닿았을때 이 매소드를 불러 온다. 이 메소드는 모든 터치의 set을 받으며 그것으로 오직 하나의 터치 오브젝트만 내보내게 된다. (모든 정보를 다 받지만 한 손가락에 대한 정보만 사용 한다는 뜻). UITouch 오브젝트에 이쓴ㄴ 정보는 터치가 발생한 view의 신원을 확인하기 위해 사용 된다(MoveMeView오브젝트인지 PlacardView 오브젝트 인지) 그리고 터치의 탭 횟수에 관련이 되있다. (더블텝인지 싱글 텝인지). 만약 터치가 버튼의 바깥쪽에서 더블텝으로 판명이 난다면 touchesBegan:withEvent메소드는 버튼의 Welcome String을 바꾸기 위해 setupNextDisplayString 메소드를 불러온다. 만약 이벤트가 Welcome 버튼의 안쪽에서 일어난다면 그것은 버튼을 키우고 손가락의 위치를 추적하기 위해 animateFirstTouchAtPoint: 메소드를 사용 한다. 다른 모든 터치들은 무시 된다.
아래의 그림은 MoveMeView 클래스의 touchesMoved:withEvent: 메소드를 보여 준다. 시스템은 손가락이 디바이스에 닿은 다음 이 메소드를 불러 온다. 그리고 원래의 자리로 부터 손가락의 위치가 움직이면 반응한다. 무브미 어플리케이션은 Welcome 버튼에 일어난 움직임에 대해서만 추적을 한다. 그 결과 이 매소드는 이벤트의 위치를 확인하며 PlacardView오브젝ㅌ의 센터 포인트를 조정하기 위해 사용 된다. view의 움직임은 그것이 자동적으로 새로운 위치를 찾기 위한 원인이 된다.
마침내 유저의 손가락이 스크린에서 떨어지게 되면 MoveMe 어플리케이션은 버튼을 어플리케이션 윈도우의 중앙인 시작 점으로 보내기 위한 에니매이션을 실행 한다. 다음은 애니메이션을 실행 시키는 ToucheEnded:withEvent: 매소드이다.
이밴트 핸들링 프로세스를 단순화 하기 위해 touchesEnded:withEvent: 메소드는 버튼이 원래의 위치로 돌아가는 동안 view의 터치 이벤트를 일시적으로 비 활성화 시킨다. (에니매이션이 작동하는 동안의 터치는 무시된다. ) 만약 이렇게 되지 않는다면 각각의 이벤트 핸들링 메소드는 버튼이 애니메이션 작동중인지 아닌지를 알아내야할 필요가 있을 것이다. 만약 그렇다면 애니메이션을 취소한다. (만약 비활성이 안된다면 터치를 인지하고 에니매이션을 중간에 끊어 버린다.) 짧은 시간동안 유저의 상호작용을 비활성화 하는 것은 버튼을 스크린의 중앙으로 보내며 이밴트 핸들링 코드를 단순화 하고 추가 논리리의 필요성을 제거 한다. 그것의 원래 자리로 돌아 옴으로서 MoveMeView클래스의 animationDidStop:finished매소드는 유저의 상호작용을 다시 활성화 시킴으로서 모든 이벤트 사이클은 다시 처음부터 작동할 수 있게 된다.
만약 어플리케이션이 전화가 온다든가 해서 중간에 방해를 받게 된다면 view는 touchesCancelled:withEvent: 메세지로 보내진다. 이런 상황에서 어플리케이션은 디바이스의 리소스를 최소화 하기 위해 노력한다. 다음의 예제에서 placard view의 중앙과 변환은 그들의 단순히 원래 값으로 저장이 된다.
iOS에서의 핸들링 이벤트에 관한 더 많은 정보를 얻기 위해서는
iOS Application Programming Guide의 "Document Revision History"를 참조 하세요.
Animating the Button's Movement!!아이폰 어플에서 에니메이션의 실행은 매우 중요한 역할을 한다. 에니메이션은 유저에게 정확한 정보와 즉각적인 피드백을 제공한다. 예를 들어 유저가 하나의 스크린을 다른 스크린으로 대체 하는 대신 생산성 어플리케이션 안에서의 계층적 데이타를 탐험 할때에 아이폰 어플리케이션은 각 새로운 스크린을 위치 시키기 위해 에니메이션을 사용한다. 에니메이션 움직임의 방향은 유저가 올리는지 내리는지를 보여주고 보고있는 새로운 정보가 있음을 비쥬얼 큐로 제공한다.
이것의 중요성 때문에 애니메이션의 지원은 UIKit의 클래스에 이미 탑재가 되어 있다. MoveMe어플리 케이션은 Welcome 버튼의 다른 양상의 애니메이션을 구현함으로서 이러한 지원의 이점을 얻는다. (UIKit의 애니메이션 지원을 사용 했다는 얘기..;;). 유저가 처음으로 버튼을 터치 했을때 어플리케이션은 버튼의 사이즈를 빠르게 확대 시키는 애니메이션을 적용한다. 유저가 버튼을 놓았을때 또다른 애니메이션이 그것을 원래의 자리로 돌리기위해 작동한다. 이러한 애니메이션의 작성의 기본 스텝은 기본적으로 같다.
- View의 beginAnimations: context: 메소드를 불러 온다.
- 에니매이션 프라퍼티를 설정한다.
- View의 에니매이션을 시작하기 위해 commitAnimations매소드를 불러 온다.
아래의 그림은 버튼을 첫 터치시 펄스를 사용하기 위한 애니메이션 코드를 보여 준다. 이 메소드는 애니메이션의 길이를 지정하고 그것의 새로운 사이즈를 비율적으로 적용한 버튼의 변화를 적용 시킵니다. 이 애니메이션이 완료 되었을때 애니메이션은 버튼을 약간 줄어들게하고 터치 아래의 placard veiw를 움직이는 펄스 애니메이션을 완료하는 애니메이션 델리게이트의 growAnimationDidStop:finished:context: 매소드를 불러옵니다.
빌트인 view기반 에니매이션의 사용에 대한 더 많은 정보를 얻기 위해 iOS Application Programming Guide의 "Animation Views"를 참조 하세요. 코어 애니메이션에 관한 더많은 정보를 iOS Application Programming Guide의 "Applying Core Animation Effects"를 참조 하세요.
Finishing the Application!!부터는 다음 포스트에 올릴께요!
최근 덧글