블로그 이미지
'무른모'란 부드럽다라는 뜻을 가진 '무르다'라는 말과 도구, 연장을 뜻하는 '연모'라는 순 우리말의 합성어로 소프트웨어를 말합니다. seanhigher

카테고리

분류 전체보기 (161)
Blog srart (16)
Dev Center (94)
Real Life (13)
Mac life (21)
Naver life (17)
Total633,817
Today41
Yesterday88
유틸리티어플리케이션의 경우는 두개의 화면만으로는 부족한 경우가 많다. 다양한 화면의 선택의 폭을 넓혀주는 것이 있는데, 그것이 탭바 어플리케이션이다.


TabBar 어플리케이션.
Xcode를 실행하고 새로운 프로젝트를 생성한다. 프로젝트 템플릿은 탭바 어플리케이션으로 선택하도록 한다.


그림1. 새 프로젝트

Xcode가 실행되고 'Resource' 폴더를 보면 'MainWindow.xib' 와 'SecondView.xib' 의 두개의 파일이 있는 것을 볼 수가 있다. 첫번째것은 탭바와 첫번째 화면을 나타낸다. 두번째는 두번째 탭을 선택했을때 나타나는 화면을 나타낸다. Xcode에서 이것을 그대로 실행하면 다음과 같이 실행되는 것을 볼 수 있다.


그림2. 탭바 어플리케이션 실행.

첫번째 탭과 두번째 탭을 번갈아가면서 눌러보면 화면이 바뀌는 것을 볼 수 있을 것이다. 각가의 화면들을 변경하기 위해서 Xcoed 로 돌아와서 'MainWindow.xib' 파일을 더블클릭하여 인터페이스 빌더를 실행시킨다. 첫번째 탭의 선택화면을 변경하고 싶다면 첫번째 'MainWindow.xib' 파일을 변경하면 되고, 두번째 탭의 화면을 변경하고 싶다면, 'SecondView.xib' 파일을 수정하면 된다.


더 많은 탭바 추가하기.
단 두개의 화며으로 이루어진 탭바는 그렇게 유용하게 쓰일 수 없다. 단 두개의 화면이라면 유틸리티 윈도우가 훨씬 멋있게 나타나고 공간도 더 넓게 사용할 수 있는 이점이 있기 때문이다. 하지만 탭바를 사용하는 이유는 바로 그것 때문이다. 더 많은 메뉴를 추가하는 것이 가능하다는 것이다! 메뉴에서 'File' -> 'New File'을 차례로 선택하여 새로운 파일을 생성하도록 한다. 파일형식은 'Cocoa Touch Class' 에서 'UIView Controller subclass'을 선택한다. 여기서 기억해야 할것은 아래의 체크박스중에서 'With XIB for user interface' 에 체클를 하고 파일을 생성해야 한다는 것이다.


그림3. 새로운 파일 생성


파일의 이름을 정하고 'finish' 버튼을 누르면 똑같은 파일명으로 '.h' '.m' '.xib' 세개의 파일이 생성되는것을 볼 수 있다. 각각의 파일이 생성된것을 확인한 후 'MainWindow.xib'파일을 인터페이스 빌더로 실행한다. 그리고 main 윈도우에서 'TabBarController'를 선택하고 Attribute 창을 실행시키도록 한다.


그림4. 탭바 Attribute 항목

애트리뷰트 항목의 맨 윗 부분을 보면 두개의 탭 항목이 있는 것을 볼 수 있다. '+' 버튼을 눌러서 항목을 추가할 수 있다. 여러개의 항목이 필요하다면 더 많이 추가하는 것이 가능하다. 많은 항목을 추가하면 그 갯수만큼 새 클래스 파일을 생성해주어야 한다. 탭바의 항목을 추가하면 main 윈도우에 컨트롤러 항목이 두개에서 더 늘어난 것을 볼 수 있다.


그림5. 탭바 항목 추가

main 윈도우에 새로 추가된 항목을 선택하고 애트리뷰트창을 띄운다. 항목을 보면 NIB name 이라는 것이 있는데 이것을 아까 새로 만들었던 파일의 이름을 선택하도록 한다. 그리고 아이덴티티창으로 이동한 후 class 를 동일한 이름으로 바꾸어준다. View 화면에서 세번째 탭을 선택했을때 다음과 같은 화면이 나온다면 제대로 설정이 된 것이다.


그림6. 세번째 탭바 항목 추가.

위의 그림에서 파란색 'thirdView'의 이름의 세번째라서 그렇게 나오는것이 아니라 파일명을 그렇게 생성했기 때문에 그렇게 나오는 것이다. 다른이름으로 클래스를 생성했다면 다른 이름으로 되어 있을 것이다. 세번째의 화면을 수정하고 싶다면 파란색 링크를 클릭하여 나오는 '뷰'를 수정하면 된다. 만일 나오지 않는다면 이름을 잘못 입력했을 가능성이 크므로 다시 처음부터 천천히 해보길 바란다.


그림7 실행 화면

이제 실행을 하면 세개의 탭으로 된 탭바 애플리케이션을 볼 수 있을 것이다. 이제 좀더 많은 메뉴를 가진 에플리케이션을 만들 준비가 되었다.

Posted by seanhigher

댓글을 달아 주세요

맥을 사용하다보면 대쉬보드라는 편리한 기능이 있다. 다양한 위젯들을 바탕화면에 깔아놓고 사용하는 것이다. 화면적 제약이 있는 아이폰에서는 대쉬보드의 기능을 가질 수는 없지만, 단일 뷰 형태의 표현이 가능하다. 날씨라던가, 간단한 시세정도라면 매우 보기 좋을 것이다!


UtilityApplication 만들기.
Xcode 를 실행하고 새 프로젝트를 실행한다. 프로젝트 형식은 UtilityApplication 을 선택하도록 한다. 이것은 단일화면으로 이루어진 위젯 형태의 프로젝트를 기본적으로 생성해주어서 편하게 작업을 할 수 있다.


그림1. 프로젝트 생성

유틸리티 어플리케이션을 생성하고, 프로젝트명을 입력하도록 한다. 이전에 해왔던 어플리케이션과 마찬가지로 Xcode가 실행되지만, 평소보다는 많은 파일들이 있는것을 볼 수 있다.


그림2. Xcode 화면

유틸리티 어플리케이션의 경우에는 두개의 창이 변환되는 형식으로 되어 있다. 창의 변화를 확인하기 위해서 이미지를 추가한다. 프로젝트에 이미지를 추가하기 위해서는 이미지파일을 끌어다가 놓으면 된다. 템플릿을 통해 만들어진 프로젝트는 두개의 창이 버튼을 통해 변환되는 구조를 가지고 있다. 처음에 나타나는 화면은 'MainView.xib' 파일을 통해 나타난다. 'MainView.xib'파일을 더블클릭하여 인터페이스 빌더를 실행한다. 필요에 따라 이미지와 라벨등을 넣도록 한다. 라이브러리가 곂쳐서 뒤에 있는 것이 보이지 않는다면 'MainView.xib' 창에서 라이브러리항목을 아래로 내릴수록 보여지는 것은 가장 위로 올라가게 된다.


그림3.  인터페이스 빌더

화면 수정을 마쳤다면 저장을 하고 인터페이스 빌더를 종료하도록 한다. 이제 실행버튼을 누르면 시뮬레이터가 실행되고 위젯 형태의 어플리케이션이 실행되는 것을 볼 수 있을 것이다.


그림4. 어플리케이션 실행화면

'MainWindow.xib' 파일은 화면전환이 이루어질때 뒤에 있는 배경화면뷰이고, 'FlipsideView.xib' 파일은 전환된 화면을 나타낸다. 이제 위젯정도의 간단한 프로그램은 어렵지 않게 만들 수 있는 것이다.

Posted by seanhigher

댓글을 달아 주세요

내가 가지고 있는 정보를 어디론가 보낸다던지, 가지고 있는 파일을 삭제한다는 것은 간단해 보일 수도 있는 작업이다. 하지만, 그 정보가 나의 모든 재산을 누군가가 가로챌 수 있는 정보라면? 내가 꼭 기억해야 할 사실을 삭제되어야 한다면? 매우 중요한 사항을 결정하게 될때, 그것을 다시한번 확인하게 해주는 것은 불의의 사태를 막는 하나의 방법으로 사용될 수 있다.



액션시트와 경고창.
액션시트와 경고창은 그 근본이 크게 다르지 않다. 사용자로부터 지금 하고자 하는 사실이 확실한지를 확인해주는 역할을 하게 된다. 사용자의 입력을 받는 경우라면 버튼을 사용해도 되는데, 궂이 액션시트라는 것과, 경고창이 왜 필요할까? 그것은 선택을 받아야 하는 정보가 어플리케이션을 진행하는데 있어서 꼭 피요한 정보이기 때문이다. 만약 화장실을 가야 하는데 사용자가 남자인지, 여자인지 알려주지 않았다면 어디로 들어가야 할찌 모르고 고민을 하게 된다. 이럴땐, 액션시트를 열어서 '남자' 또는 '여자' 둘중에 선택할 수 있도록 만들어야 한다. 그리고 경고창은 매우 중요한 결정을 할 때 사용될 수 있다. 내가 내년까지 기억해야 할 정보를 깜빡하고 삭제하려고 한다면, 경고창을 보여주면서 그 기록에 대해 다시한번 확인시켜준다.


레이아웃 디자인하기.
새로운 프로젝트를 'alermTest' 란 이름으로 생성한다. 종류를 View-based Application 으로 선택한다. Resources 폴더 안에 있는 'alerm-TestViewController.xib' 파일을 더블클릭하면 인터페이스 빌더를 실행할 수 있다. 레이아웃은 매우 간단하다. 화면의 가운데에 'action' 이라는 버튼을 한개 가져다 놓고, 이름을 'action' 으로 바꾸어주면 끝이다. 인터페이스 빌더를 실행한 후, 라이브러리에서 버튼을 드래그 해서 뷰 영역으로 옮겨놓은 일은 어렵지 않을 것이다.


그림1. 인터페이스 디자인


아웃렛과 액션을 설정하는 간편한 방법.
아웃렛과 액션을 생성하기 위해서는 Xcode 창에서 각각의 소스코드를 입력해서 작성해 주어야 인터페이스 빌더의 화면에 나오게 되었다. 이렇게 직접 소스코드를 입력하는 것이 쉬운 방법일 수도 있겠지만, 더욱더 간단하게 마우스 클릭만으로도 아웃렛과 액션을 생성하는 것이 가능하다.


그림2. 인터페이스 빌더에서 액선, 아웃렛 선언.

라이브러리 윈도우를 보면 맨 위에 Library, Classes, Media 의 세가지 탭이 있는데 이중에 Classes 항목을 선택한다. 항목을 선택하면 바로 아래에 라이브러리들이 나오게 되는데 우리가 사용하게 될것은 ViewController 이므로 alermTestViewController 항목을 선택하도록 한다. 가장 아래부분에는 선택된 항목의 정보가 간단하게 나오게 된다. 먼저 액션을 추가하기 위해 가장 오른쪽의 'Actions' 항목을 선택한다. 아래의 '+' 버튼을 클릭하여 새로운 액션을 추가, 이름을 변경해준다. 아웃렛을 추가하기 위해서는 'Outlets' 항목으로 이동해야 한다. 액션을 추가할때와 마찬가지로 '+' 버튼을 클릭하여 새로운 아웃렛을 추가하고 이름을 변경하여 준다. 이것으로 새로운 액션과 아웃렛의 생성이 간단하게 마무리 되었다.


액션, 아웃렛 이어주기.
액션과 아웃렛을 선언만 한다고 해서 사용이 가능한 것은 아니다. 이것을 사용할 수 있도록 서로 연결해 주는 작업이 필요하다.


그림3. 아웃렛 연결.

'View' 윈도우에서 버튼을 선택한후, 'Connections' 윈도우를 연다. 아래쪽을 보면 'Referencing Outlet' 항목의 'New Referencing Outlet' 을 선택하여 아웃렛을 추가하도록 한다. 오른쪽에 있는 원에 마우스 커서를 가져가면 십자가 모양으로 변하게 되고, 그것을 끌어다가 메인 위도우의 File's Owner 아이콘으로 가져다 놓는다. 그러면 위의 그림과 같이 아웃렛으로 선택하 수 있는 항목이 나타나게 되는데, 이미 만들어 놓았던 아웃렛인 'actionButton'을 선택하도록 한다.


그림4. 액션 연결하기.

액션을 연결하는 방법도 아웃렛을 연결하는 것과 거의 동일하다. 단지 항목을 'New Referencing Outlet' 항목이 아닌, 'Events' 항목에서 선택을 한다는 것이 다르다. 버튼을 클릭하는 것이기 때문에 'Touch Up inside' 의 항목을 끌어다 File's Owner 아이콘에 가져다 놓는다. 그리고 선택할 수 있는 액션 항목이 나타나는데, 이전에 선언한 'actionsh' 액션을 선택하도록 한다.


인터페이스 빌더로 소스파일 생성.
아웃렛과 액션을 선언하고 연결하는 일을 마무리 지었다. 하지만, 이상태에서는 다시 Xcode 로 돌아가도 소스코드에는 변화가 없다. Xcode 의 내용이 인터페이스에 반영되기 위해서는 소스코드를 저장하기만 하면 바로 적용이 가능했지만, 반대로 인터페이스 빌더의 내용을 소스코드에 반영하기 위해서는 인터페이스 빌더가 소스코드를 작성하는 과정이 필요하다.


그림5. Write Class Files 작업.

alermTestViewController가 선택된 상태에서 맨 왼족 아래의 메뉴(톱니바퀴 모양) 버튼을 클릭하면 위와 같은 메뉴가 나오는것을 볼 수 있다. 윗부분의 'Write Updated Class Files' 버튼을 클릭하여 변경된 사항을 소스코드에 적용할 수 있다. 파일은 'alermTestViewContoller.m' 파일을 선택하고 'Replace' 버튼을 선택하여 새로운 내용으로 대체하도록 한다. 이제 소스코드를 보면 변경된 내용이 적용되어 있을 것을 볼 수 있다.


액션시트 델리게이트.
델리게이트는 다양한 객체와 클래스, 메소드들을 묶어서 다양한 행동을 확장해 주는 역할을 한다. 또, 액션시트와 경고창을 사용하기 위해서는 컨트롤러 클래스가 델리게이트를 사용해야 하는데, 'UIActionSheetDelegate' 라는 프로토콜을 따르도록 만들어 주어야 한다. 델리게이트를 선언해주기 위해서는 클래스명 다음에 '<UIActionSheetDelegate>' 를 추가해 주기만 하면 된다.

@interface alermTestViewController : UIViewController
<UIActionSheetDelegate> {
    IBOutlet id actionButton;
}



액션시트 추가하기.
액션을 통해서 무언가 실행이 되게 하기 위해서는 액션메서드를 구현하는 과정이 필요하다. 또한 액션시트가 닫힐때 이루어지는  액션 메소드도 필요하다.

@implementation alermTestViewController
- (IBAction)actionsh:(id)sender {
    UIActionSheet *actionSheet = [[UIActionSheet alloc]
                                  initWithTitle: @"Are you sure?"
                                  delegate: self
                                  cancelButtonTitle: @"No way!"
                                  destructiveButtonTitle: @"Yes, I' sure!"
                                  otherButtonTitles: @"second", @"third", nil];
    [actionSheet showInView: self.view];
    [actionSheet release];
}

위의 소스틑 액션시트를 만들어 준다. 액션시트는 UIActionSheet 클래스로 선언되어진다. 액션시트가 가지게 되는 다양한 인자가 있는데 첫번째로 'initWithTitle' 는 액션시트의 제목의 내용을 나타낸다. delegate 항목은 시트에 있는 버튼이 눌려졌을때 알려주는 역할을 하게 된다. self를 선언함으로 자기 자신을 호출하게 된다. 액션시트에는 취소하는 항목을 기본적으로 가지게 되는데, 'cancelButtonTitle' 는 이것을 설명하는 문구를 정하게 된다. 이와 반대로 'destructiveButtonTitle' 는 실행 버튼을 생성해주며, 사용될 문구를 정할 수 있다. 마지막에 있는 'otherButtonTitles' 는 더 추가되는 버튼을 표현하게 되는데, 마지막을 의미하는 'nil' 이 나타나기 전까지 여려개를 늘릴 수 있다. 액션시트에 대한 정의를 마무리 짓고, 'actionSheet showInView' 를 통하여 액션시트가 화면에 보여지도록 한다. 버튼을 누르면 나타나는 액션시트를 구현한 것이다.


경고창 추가하기.
경고창은 액션시트와 거의 비슷하다. 인자의형태나, 구성 또한 비슷하다. 단지 'UIActionSheet' 대신에 'UIAlertView' 를 사용한다는 것이 다르다. 다음의 소스를 위의 소스 다음에 추가하도록 한다.

- (void)actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex: (NSInteger)buttonIndex {
    if (buttonIndex != [actionSheet cancelButtonIndex]) {
        NSString *msg = nil;
        msg = @"You went OK.";
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle: @"Something was done"
                              message: msg
                              delegate: self
                              cancelButtonTitle: @"Paw!"
                              otherButtonTitles: nil];
        [alert show];
        [alert release];
        [msg release];
    }
}

'actionSheet: didDismissWithButtonIndex' 는 UIActionSheetDelegate 메소드 중 하나이다. 위의 소스에서는 이 메소드를 컨트롤러 자체로 설정하였기 액션시트의 버튼이 눌려짐과 동시에 실행이 되는 메소드가 되는 셈이다. 액션시트의 다양한 버튼중에서 어떤 버튼이 눌려졌는지 알기 위해서는 buttionIndex 의 인자를 통해 접근이 가능하다. 이번에 작성한 소스에서는 취소 버튼 외에는 특별히 인자를 구별할 필요가 없다. 그렇기 때문에 '[actionSheet cancelButtonIndex]' 만 확인을 해주면 된다. 나머지 인자는 액션시트의 인자와 동일한 역할을 하게 된다. 'message' 는 제목 이외에 추가적인 설명을 더해준다. 경고창의 경우에는 'self.view' 대신에 'show' 만을 사용했는데, 이것은 액션시트의 경우는 부모뷰에 연결되어 있는 것이고, 경고창은 독립적으로 사용되기 때문이다.


시뮬레이션.
액션시트와 경고창에 대한 작업이 모두 완료되었다. 이제 'Build and Run' 버튼을 눌러서 실행을 해보도록 하자.


그림6. 시뮬레이션

가장 왼쪽에 있는 화면은 맨 처음 어플리케이션을 실행했을 경우에 나타나게 되는 화면이다. 가운데 있는 버튼을 누르면 가운데 화면과 같은 액션시트를 보게 될 것이다. 액션시트에서는 "No way!" 버튼만 취소 버튼으로 설정해 두었기 때문에 모두 동일한 결과를 보여주게 되는데, 'Yes I'm sure!', 'second', 'third' 버튼을 누를경우엔 가장 오른쪽의 화면과 같이 경고창을 보여주게 된다. 'No way!' 버튼을 눌렀을 경우에는 다시 원래의 화면으로 돌아가게 된다.

액션시트와 경고창은 사용자에게 어플리케이션을 사용하는데 있어서 조금의 강제성을 부여한다. 하지만, 이것은 조금더 원할한 상호작용을 위한 필수 요소라고 할 수 있다. 내가 말하지도 않은 사실을 상대방이 알고있을리 만무하다.

Posted by seanhigher

댓글을 달아 주세요

아이폰 개발을 하기 위해 필요한것은 개발 도구와, 개발한 애플리케이션을 실행해 볼 수 있는 아이폰이나, 아이팟 터치일 것이다. 하지만, 아이폰/아이팟 터치가 없다면?? 컴퓨터는 누구나가 다 가지고 있기 때문에 해킨토시를 하던, VMware를 통해 설치하는 등의 방법을 통해 설치 할 수 있지만, 없는것을 만들어 낼 수는 없는 노릇이다. 그리고 매번 동기화 시켜서 테스트 할 수도 없는것이고... 다른 개발 툴들도 마찬가지겠지만, 아이폰 SDK에는 실제 실행환경과 매우 유사한 iPhone simulator 가 준비되어 있다.




아이폰 시뮬레이터 실행하기.
Xcode 로 애플리케이션을 작성하고 'Run and Build' 버튼을 누르면 소스코드가 빌드되고, 자동으로 아이폰 시뮬레이터가 실행이 된다. 그리고 지금 개발중인 애플리케이션이 실행한 상태의 화면이 나타나게 된다. 애플리케이션은 실행하지 않은채로 아이폰 시뮬레이터만 실행해 보고 싶다면 HardDisk -> Developer -> Platforms -> iPhoneSimulator.platform -> Developer -> Applications 의 순서로 폴더를 따라가다 보면 'iPhone Simulator' 실행 파일을 만날 수 있다. 이 파일을 더블 클릭하면 아이폰 시뮬레이터가 실행된다.


손가락이 없다면 마우스로...
아이폰을 가장 잘 활용하기 위한 도구는 우리 모두가 가지고 있는 손가락이다. 하지만 아쉽게도 컴퓨터에는 손가락이 없다. 대신에 마우스라는 친근한 도구가 우리에게 있다. 마우스와 마우스의 버튼은 우리가 손가락으로 아이폰에 입력할 수 있는 대부분의 입력을 충분히 입력할 수 있도록 해준다.


그림1. 아이폰 시뮬레이터의 입력

Mouse Click : 마우스를 원하는 곳에 이동한 후 클릭하는 것을 손을 아이폰의 화면에 대는 것과 같다고 할 수 있다. 무엇인가를 선택할 때 사용되고, 버튼 형식의 객체를 컨트롤 할 수 있다.
Mouse double Click : 마우스를 더블클릭하는 것은 손가락으로 빠르게 두번을 탭하는 것과 같다. 취소를 하거나, 화면 전환을 할 때, 탭 이외의 추가적인 입력이 필요할 때 사용 할 수 있다.
Mouse Click & Drag : 마우스를 클릭한 상태에서 드래그를 하는 것은 손가락을 아이폰의 화면에 대고 끄는것과 같은 역할을 하게 된다. 매우 큰 화면을 볼 때 이리저리 움직일 때 사용하거나, 화면 전환에 유용하게 쓰이는 제스쳐이다.
'option' + Mouse Click & Drag : 'option' 키를 누른 상태에서 마우스를 클릭하면 위의 화면과 같이 두개의 원이 생기게 되는데 이것은 두개의 손가락을 의미한다. 이것을 드래그하면 손가락의 간격을 줄이거나 늘이거나 할 수 있는데, 화면을 확대하거나 축소할때 손쉽게 사용하는 제스쳐이다.


아이폰 흔들기.
아이폰의 주요 특징의 하나는 위치와 방향에 대한 감각이 뛰어나다는 것이다. 아이폰을 눞이거나 세우거나하는 방식으로 좀더 효율적인 애플리케이션 사용환경을 만들어 줄 수 있고, 좌우로 기울이면서 애플리케이션을 제어할 수 있다. 그리고 흔들기도 가능하다!


그림2. 아이폰을 옆으로 Rotate 상태.

아이폰을 오른쪽으로, 또는 왼쪽으로, 아니면 뒤집어 놓으려면 메뉴를 이용해야 한다. 아이폰을 움직이는 메뉴들은 Hardware 메뉴에서 볼 수 있다.


그림3. Hardware 메뉴

Hardware 메뉴에서 'Rotate Left' 를 선택하면 아이폰이 왼쪽으로 90도 회전한다. 반대로 'Rotate Right' 를 선택하면 아이폰이 오른쪽으로 90도 회전하게 된다. 아이폰을 뒤집어 놓고 싶다면 한쪽 방향으로 두번 회전을 하면 180도를 회전하여 뒤집어진 아이폰의 모습이 된다. 단축키로 '사과' + '->' 또는 '사과' + '<-' 키를 사용할 수도 있다. 그리고 그 아래에 있는 'Shake Gesture' 는 아이폰을 흔들어주는 기능이다. 실제 에니메이션으로 아이폰이 흔들어지지는 않지만, 그 효과가 아이폰에 그대로 적용된다. 아이폰 애플리케이션을 제작하면서 흔들기 제스쳐를 포함시켰다면, 위 메뉴를 사용하여 테스트 해 볼 수 있다. 하지만 한가지 아쉬운 것은 중력센서를 컨트롤 하는 것은 아직 지원하지 않는다는 것이다.


그림4. 아이폰이 'Lock' 된 상태

아이폰에 달려있는 여러가지 버튼들을 사용하기 위해 클릭을 해보면... 아무것도 일어나지 않는다. 단지 가운데 떡하니 자리잡고 있는 홈버튼만이 작동할 뿐이다. 아직 아이폰 시뮬레이터에서는 볼륨조절버튼, 전원버튼, 락버튼등 시뮬레이터에서 보이는 버튼들을 누르는것이 가능하지 않다. 한가지 'Lock' 버튼은 hardware 메뉴에서 선택하여 실행할 수는 있다.


아이폰 시뮬레이터 리셋하기.
맨 처음 'Hello world!' 출력하기 프로젝트 부터, 점점 진화하는 다양한 프로젝트를 개발하면서 공부를 하다보면, 벌써 수많은 어플리케이션이 나도모르는 사이에 아이폰 시뮬레이터에 설치되어 있는것을 볼 수 있다. 문제는 이미 삭제한 애플리케이션까지 설치되어 있다는 것이다.

그림5. 아이폰 시뮬레이터 리셋

아이폰 시뮬레이터는 Xcode 프로젝트에서 빌드하는 모든 애플리케이션을 설치하게 된다. 그렇게 많은 애플리케이션이 설치되면 나중에는 점점 시뮬레이터에 무리가 가게 된다. 결국엔 더이상 프로젝트를 생성할 수 없는 단계에 까지 이르게 되는 것이다. 하지만, 이럴때를 위해 준비된 것이 있다. 바로 리셋! 하드웨어를 포멧하는 것과 같은 작업을 아이폰 시뮬레이터에도 하는것이 가능하다. 메뉴의 iPhone Simulator -> Reset Content and Settings... 를 차례로 선택하면 아이폰 시뮬레이터를 정말로 리셋할것인 확인을 한후 리셋을 한다. 리셋을 하고 나면 다시 쌩쌩하고 깨끗한 아이폰 시뮬레이터 환경에서 애플리케이션을 제작할 수 있을 것이다.

Posted by seanhigher

댓글을 달아 주세요

모바일 환경이라함은 한정된 공간적 제약을 가지고 있다. 그렇기 때문에 컨트롤러 하나하나를 배치하거나, 레이아웃을 작성하는데 있어서 신중을 기해야 한다. 분할 컨트롤은 이러한 공간적 제약을 조금이나마 벗어날 수 있는 기능을 제공해 준다. 백개의 버튼을 한 화면에 담을 수는 없지만, 열개씩 나누어서 볼 수 있다면 충분히 넉넉하게 볼 수가 있다.


New project.
새로운 프로젝트를 시작한다. 'View-based Application' 을 선택하고 프로젝트 이름은 'roomControl' 로 하였다. 이번에 만들게 될 애플리케이션은 방의 불을 On/Off 하는기능, 온도를 조절하는 기능, 스텝을 호출하는 기능을 분할컨트롤 버튼을 이용하여 선택적으로 보여지게 한다. 우선은 프로그램에 대한 구상을 한다.


그림1. 프로젝트 구상

애플리케이션을 구상하는데 있어서 가장 먼저 해야 할 것은 아웃렛과 액션을 선언해야 하는 부분은 어떤 부분인가이다. 이 프로젝트에서는 분할 컨트롤을 선택하여 모든 객체에 hidden 메소드를 이용해야 하기때문에 표현되는 모든 라벨, 버튼, 스위치, 슬라이더 객체가 아웃렛으로 선언되어야 한다. 또한 액션으로는 어떠한 액션이 정의되어야 하는지 계획해야 한다.


첫번째 segmented Control
모든 화면을 한꺼번에 설명하기엔 양이 조금 많을 수 있기 때문에 한 화면씩 구체화 하도록 한다. 분할 컨트롤은 슬라이더와 마찬가지로 이미 아웃렛이 선언되어 있기 때문에 임의로 선언할 필요는 없다. 하지만, 분할 컨트롤의 선택에 대한 액션은 구현해 주어야 한다. 액션을 구현해 주지 않으면 분할컨트롤 객체가 무엇을 해야 할찌 모르기 때문이다. 첫 분할컨트롤은 방의 불을 조절하는 스위치와 라벨이 자리하고 있다. 세개의 스위치와 세개의 라벨이 모두 아웃렛으로 선언되어야 한다. 그리고 스위치는 On/Off 를 표시할 수 있도록 액션이 선언되어야 한다. 분할컨트롤와 첫번재 컨트롤에 들어가는 아웃렛은 다음과 같이 선언할 수 있다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    UISwitch *roomLight1_Switch;
    UISwitch *roomLight2_Switch;
    UISwitch *indoorLight_Switch;
    UILabel *roomLight1_Label;
    UILabel *roomLight2_Label;
    UILabel *indoorLight_Label;
}

@property (nonatomic, retain) IBOutlet UISwitch *roomLight1_Switch;
@property (nonatomic, retain) IBOutlet UISwitch *roomLight2_Switch;
@property (nonatomic, retain) IBOutlet UISwitch *indoorLight_Switch;
@property (nonatomic, retain) IBOutlet UILabel *roomLight1_Label;
@property (nonatomic, retain) IBOutlet UILabel *roomLight2_Label;
@property (nonatomic, retain) IBOutlet UILabel *indoorLight_Label;

- (IBAction) toggleControls: (id) sender;
- (IBAction) switchChange: (id)sender;


<roomControlViewController.m>
@implementation roomControlViewController

@synthesize roomLight1_Switch;
@synthesize roomLight2_Switch;
@synthesize indoorLight_Switch;
@synthesize roomLight1_Label;
@synthesize roomLight2_Label;
@synthesize indoorLight_Label;

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        roomLight1_Switch.hidden = NO;
        roomLight2_Switch.hidden = NO;
        indoorLight_Switch.hidden = NO;
        roomLight1_Label.hidden = NO;
        roomLight2_Label.hidden = NO;
        indoorLight_Label.hidden = NO;
    } else if([sender selectedSegmentIndex] == 1) {
        roomLight1_Switch.hidden = YES;
        roomLight2_Switch.hidden = YES;
        indoorLight_Switch.hidden = YES;
        roomLight1_Label.hidden = YES;
        roomLight2_Label.hidden = YES;
        indoorLight_Label.hidden = YES;
    } else if([sender selectedSegmentIndex] == 2) {
        roomLight1_Switch.hidden = YES;
        roomLight2_Switch.hidden = YES;
        indoorLight_Switch.hidden = YES;
        roomLight1_Label.hidden = YES;
        roomLight2_Label.hidden = YES;
        indoorLight_Label.hidden = YES;
    }
}

- (IBAction) switchChange: (id)sender {
    UISwitch *whichSwitch = (UISwitch *)sender;
    BOOL setting = whichSwitch.isOn;
    [roomLight1_Switch setOn:setting animated:YES];
    [roomLight2_Switch setOn:setting animated:YES];
    [indoorLight_Switch setOn:setting animated:YES];
}

... ... ...

- (void)dealloc {
    [roomLight1_Switch release];
    [roomLight2_Switch release];
    [indoorLight_Switch release];
    [super dealloc];
}


위 소스코드에서 toggleControls 액션은 분할컨트롤에 대한 액션이다. 액션 개체는 sender 라는 인자를 통해 값을 전달받을 수 있는데, 분할컨트롤은 선택영역에 따라 인덱스값을 받을 수 있다. 분할컨트롤의 분할컨트롤의 첫번째는 '0', 두번째는 '1', 세번째는 '2' 와 숫자의 배열 형식을 갖는다. 이 값은 'selectedSgmentedIndex' 라는 변수값으로 구분지을 수 있다. 이 값을 비교함으로써 분할컨트롤이 어떤 값을 선택하였는지 알 수 있게 된다. 분할컨트롤이 선택되고 '{ }' 안의 내용을 보면 hidden 이라는 메소드가 호출되는 것을 볼 수 있다. UIview 를 상속받는 모든 객체의 기본적인 메소드이며, 화면에 표시할것인지를 결정하는 요소가 된다. 'NO' 일경우는 숨기지 않겠다는 뜻으로 화면에 표시가 되고, 'YES' 값일 경우는 숨기겠다는 뜻으로 화면에 표시하지 않겠다는 뜻이 된다. switchChange 액션은 스위치가 On / Off 되는 액션을 표현한다. 중간에 setting animated 옵션은 스위치가 순식간에 변하게, 또는 애니메니션이 적용되어 변하게 되는지 설정할 수 있다.


첫번째 레이아웃 작성.
레이아웃을 작성하기 위해서는 인터페이스 빌더를 실행해야 한다. 'Resources' 폴더의 'roomControlViewController.xib' 파일을 더블클릭하여 인터페이스 빌더를 실행한다. 분할 컨트롤러를 이용한 첫번째 화면의 레이아웃을 작성한다. 라이브러리 윈도우에서 분할 컨트롤 객체, 스위치 객체를 드래그하여 뷰 윈도우의 적당한 위치에 배치시킨다. 그리고 라벨을 위치시키고 텍스트 내용을 변경한다.


그림2. 첫번째 레이아웃 작성

분할 컨트롤러는 기본적으로 두개의 선택 버튼을 기본으로 제공한다. 하지만, 위의 그림처럼 세개의 메뉴로 늘리기 위해서는 Attibute 윈도우의 segments 항목을 '2' 에서 '3'으로 늘려주면 항목수가 하나 늘어나게 된다.


액션과 아웃렛 연결하기.
액션과 아웃렛은 인터페이스 빌더를 통해 연결하지 않으면 아무 소용이 없다. 아웃렛을 연결하는 방법에는 두가지가 있다. 첫번째는 'ctrl' 키를 누른채로 main 윈도우의 File's Owner 아이콘을 클릭하고, 아웃렛을 연결하고자 하는 객체로 드래그하여 선택하는것이다. 두번째는 File's Owner 아이콘을 선택한 후 Connections 윈도우에서 아웃렛을 먼저 선택하여 원하는 객체에 연결 시키는 방법이다. 방법의 차이만 있을 뿐 다른 차이점은 없기 때문에 선호하거나, 편한 방법으로 세개의 스위치와, 라벨의 아웃렛을 연결한다. 액션을 연결하는 방법도 아웃렛을 연결하는 것과 비슷한 방식으로 이루어진다. 액션을 연결하는 방법 역시 두가지가 있다. 첫번째는 아웃렛을 연결하는 방법과 반대의 순서로 하면 된다. 'ctrl' 키를 누르는 것은 동일하고, File's Owner 에서 객체로 드래그 하는 것이 아니라, 객체를 먼저 선택한 후 File's Owner 아이콘으로 드래그하는 것이다. 그러면 Events 항목이 팝업으로 나오게 되고, 적절한 항목을 선택하면 된다.


그림3. 액션 연결하기

액션을 연결하는 두번째 방법은 File's Owner 아이콘을 선택한 후 Connections 윈도우를 이용하는 것이다. 아웃렛을 연결하는 것과 마찬가지로 Connections 윈도우를 보면 아랫부분에 Received Actions 항목에 이미 선언한 액션들을 볼 수가 있다. 원하는 액션의 항목 오른쪽으로 마우스 커서를 가져가면 원안에 십자가 모양이 생기게 된다. 이것을 액션을 연결하고자 하는 객체에 끌어다가 놓으면 팝업으로 액션 항목이 나오는데, 가장 적절한 액션을 선택하도록 한다. 스위치와 분할 컨트롤러에는 Value Changed 값이 가장 적당하다. togleControls 액션도 분할컨트롤러에 연결하도록 한다. 첫번째로 작성한 컨트롤러가 잘 작동하는지 시뮬레이션을 해보도록 한다. 분할컨트롤의 첫번째 버튼에만 화면이 나오는 것을 볼 수 있을 것이다. 만약 오류가 있어가, 생각했던대로 실행이 되지 않는다면 오류를 확인해 보고, 위에서부터 차근차근 다시 해보길 바란다.


그림4. 첫번째 분할컨트롤 작성 후 시뮬레이션 화면


두번째 Segmented Control
두번째 분할컨트롤 화면은 위와 같은 순서를 반복하면 된다. 두번째 화면에서는 슬라이더에 의한 제어를 하기 때문에 세개의 슬라이더와 세개의 라벨이 필요하다. 다음과 같이 코드를 입력한다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    ... ...

    UILabel *roomTmep1_SliderLabel;
    UILabel *roomTemp2_SliderLabel;
    UILabel *indoorTemp_SliderLabel;
    UISlider *roomTemp1_Slider;
    UISlider *roomTemp2_Slider;
    UISlider *indoorTemp_Slider;

}
... ...

@property (nonatomic, retain) IBOutlet UILabel *roomTmep1_SliderLabel;
@property (nonatomic, retain) IBOutlet UILabel *roomTemp2_SliderLabel;
@property (nonatomic, retain) IBOutlet UILabel *indoorTemp_SliderLabel;
@property (nonatomic, retain) IBOutlet UISlider *roomTemp1_Slider;
@property (nonatomic, retain) IBOutlet UISlider *roomTemp2_Slider;
@property (nonatomic, retain) IBOutlet UISlider *indoorTemp_Slider;

... ...

- (IBAction) SliderChangeRoom1: (id)sender;
- (IBAction) SliderChangeRoom2: (id)sender;
- (IBAction) SliderChangeIndoor: (id)sender;


<roomControlViewController.m>
... ...
@synthesize roomTmep1_SliderLabel;
@synthesize roomTemp2_SliderLabel;
@synthesize indoorTemp_SliderLabel;
@synthesize roomTemp1_Slider;
@synthesize roomTemp2_Slider;
@synthesize indoorTemp_Slider;
... ...

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        ... ...

        roomTmep1_SliderLabel.hidden = YES;
        roomTemp2_SliderLabel.hidden = YES;
        indoorTemp_SliderLabel.hidden = YES;
        roomTemp1_Slider.hidden = YES;
        roomTemp2_Slider.hidden = YES;
        indoorTemp_Slider.hidden = YES;
    } else if([sender selectedSegmentIndex] == 1) {
        ... ...

        roomTmep1_SliderLabel.hidden = NO;
        roomTemp2_SliderLabel.hidden = NO;
        indoorTemp_SliderLabel.hidden = NO;
        roomTemp1_Slider.hidden = NO;
        roomTemp2_Slider.hidden = NO;
        indoorTemp_Slider.hidden = NO;
    } else if([sender selectedSegmentIndex] == 2) {
        ... ...

        roomTmep1_SliderLabel.hidden = YES;
        roomTemp2_SliderLabel.hidden = YES;
        indoorTemp_SliderLabel.hidden = YES;
        roomTemp1_Slider.hidden = YES;
        roomTemp2_Slider.hidden = YES;
        indoorTemp_Slider.hidden = YES;
    }
}
... ...

- (IBAction) SliderChangeRoom1: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Room1 temperature is %d degrees", progressAsInt];
    roomTmep1_SliderLabel.text = newText;
    [newText release];
}

- (IBAction) SliderChangeRoom2: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Room2 temperature is %d degrees", progressAsInt];
    roomTemp2_SliderLabel.text = newText;
    [newText release];
}

- (IBAction) SliderChangeIndoor: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Indoor temperature is %d degrees", progressAsInt];
    indoorTemp_SliderLabel.text = newText;
    [newText release];
}
... ...

- (void)dealloc {
    ... ...

    [roomTmep1_SliderLabel release];
    [roomTemp2_SliderLabel release];
    [indoorTemp_SliderLabel release];
    [roomTemp1_Slider release];
    [roomTemp2_Slider releasd];
    [indoorTemp_Slider release];
    [super dealloc];
}

첫번째 화면을 작성하면서 작성했던 소스코드에 위의 내용을 추가하면 된다. 슬라이더의 경우 일반적으로 아웃렛을 선언하지 않아도 그 값을 받아 사용할 수 있지만, 이번 프로젝트에서는 분할컨트롤러를 이용할때 hidden 옵션을 사용해야 하기 때문에 아웃렛을 선언하여 hidden 옵션을 사용할 수 있도록 하였다. 화면의 작업을 마친 후에는 분할컨트롤의 항목도 신경을 써 주어야 한다. 어느 버튼을 선택했을때 보여야 할찌 각 객체별로 모두 선언을 해 주어야 한다. 각 슬라이더의 액션은 슬라이더의 인자값을 받아서 라벨에 출력하는 액션이다. 먼저 슬라이더의 인자값을 구하고, 정수형으로 변환한 후 텍스트 형식으로 바꾸어 준다. 그리고 아웃렛으로 선언된 라벨에 출력해준다. 코딩을 하면서 retain 으로 선언된 모든 객체들은 꼭 release를 해서 자원의 낭비를 막아야 한다는 것을 잊지 말기 바란다.


화면디자인하고, 아웃렛과 액션 연결하기.
다시 인터페이스 빌더로 이동하여 화면을 디자인하도록 한다. 분할 컨트롤을 사용하는 경우 이미 객체들이 배치되어 있는 상태에서 그 위에 또 다른 객체를 표현하는 것이기 때문에 화면 하나씩 순서대로 작성하는 것이 화면을 구성하는데 불편함을 덜 수 있다.


그림5. 화면디자인및 아웃렛, 액션 연결

첫번째 페이지를 만들때와 동일한 방법으로 뷰 윈도우의 객체들과 아웃렛을 이어주고, 액션을 연결해 주면 된다. 한가지 주의해야 할 점은 두번째 화면의 객체들은 Attribute 윈도우에서 View -> Drawing -> Hidden 을 체크해 주어야 한다. 그렇지 않으면 처음 화면에서 위의 화면과 같이 겹치는 화면을 보게 될 것이다.


세번째 Segmented Control
세번째는 버튼을 이용한 화면이다. 버튼을 이용한 액션을 가장 기초적인 액션이기 때문에 어렵지 않게 구현할 수 있어야 한다. 잘 모르겠다면 이전의 포스팅을 보면서 버튼을 구현하도록 한다. 이 프로젝트에 필요한 버튼은 여섯개이다. 버튼의 내용을 표현하기 위한 하나의 라벨이 필요하다. 또 버튼의 내용을 인자값으로 전달받아서 출력하기 위한 액션을 추가한다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    ... ...

    UIButton *roomStaff1_Button;
    UIButton *roomStaff2_Button;
    UIButton *roomStaff3_Button;
    UIButton *roomStaff4_Button;
    UIButton *roomStaff5_Button;
    UIButton *roomStaffAll_Button;
    UILabel *callStaff;

}
... ...

@property (nonatomic, retain) IBOutlet UIButton *roomStaff1_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff2_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff3_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff4_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff5_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaffAll_Button;
@property (nonatomic, retain) IBOutlet UILabel *callStaff;

... ...

- (IBAction) buttonPress: (id)sender;


<roomControlViewController.m>
... ...
@synthesize roomStaff1_Button;
@synthesize roomStaff2_Button;
@synthesize roomStaff3_Button;
@synthesize roomStaff4_Button;
@synthesize roomStaff5_Button;
@synthesize roomStaffAll_Button;
@synthesize callStaff;

... ...

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        ... ...

        roomStaff1_Button.hidden = YES;
        roomStaff2_Button.hidden = YES;
        roomStaff3_Button.hidden = YES;
        roomStaff4_Button.hidden = YES;
        roomStaff5_Button.hidden = YES;
        roomStaffAll_Button.hidden = YES;
        callStaff.hidden = YES;

    } else if([sender selectedSegmentIndex] == 1) {
        ... ...

        roomStaff1_Button.hidden = YES;
        roomStaff2_Button.hidden = YES;
        roomStaff3_Button.hidden = YES;
        roomStaff4_Button.hidden = YES;
        roomStaff5_Button.hidden = YES;
        roomStaffAll_Button.hidden = YES;
        callStaff.hidden = YES;

    } else if([sender selectedSegmentIndex] == 2) {
        ... ...

        roomStaff1_Button.hidden = NO;
        roomStaff2_Button.hidden = NO;
        roomStaff3_Button.hidden = NO;
        roomStaff4_Button.hidden = NO;
        roomStaff5_Button.hidden = NO;
        roomStaffAll_Button.hidden = NO;
        callStaff.hidden = NO;

    }
}
... ...

- (IBAction) buttonPress: (id)sender {
    NSString *title = [sender titleForState:UIControlStateNormal];
    NSString *newText = [[NSString alloc] initWithFormat: @"%@ called", title];
    callStaff.text = newText;
    [newText release];
}

... ...

- (void)dealloc {
    ... ...

    [roomStaff1_Button release];
    [roomStaff2_Button release];
    [roomStaff3_Button release];
    [roomStaff4_Button release];
    [roomStaff5_Button release];
    [roomStaffAll_Button release];
    [callStaff release];

    [super dealloc];
}

위에서 분할 컨트롤과, 스위치, 슬라이더에 대한 액션을 구현했다면 나머지 버튼을 구현하는 것은 크게 어렵지 않다. 위 소스 코드를 참조하여 코딩을 하도록 한다. buttonPress 액션은 각 버튼에 대한 값들을 받아와서 새로운 문자열을 만들고, 선언된 라벨에 출력하는 액션이다. 분할컨트롤에 항목을 추가하는 것과, 객체들을 release 하는것도 빠뜨리지 않고 하도록 한다. 모든 프로그래밍을 마친 후에는 인터페이스 빌더로 이동하여 인터페이스 디자인을 한다.


그림6. 세번째 분할컨트롤 화면 구현

이전의 인터페이스들이 그대로 보여지기 때문에 화면에 매우 복잡해지기 시작한다. 하나하나 잘 체크해가며 객체들을 배치하도록 한다. 객체를 배치한 후에는 아웃렛을 연결하고, 액션들을 연결하도록 한다. 어렵지 않게 마지막 화면을 마무리 할 수 있을 것이다.


그림7. 완성된 애플리케이션 시뮬레이션

위와 같이 분할컨트롤로 애플리케이션을 제작하면 더 많은 정보들을 좀더 효율적으로 보여줄 수 있다.

Posted by seanhigher

댓글을 달아 주세요

Object-C 프로그래밍에 있어서 델리게이트는 매우 중요한 요소라고 할 수 있다. 게다가 이 델리게이트는 아이폰 애플리케이션의 생명주기와도 깊은 연관이 있다. 델리게이트가 없다면 생명을 잃어버린 애플리케이션이라고 말 할 수 있다.



애플리케이션의 생명주기.
어떤 프로그래밍 언어이든지, 프로그램이 소스 코드를 통하여 메모리에 적재되고, 각자 정해진 위치에서 역할을 수행하고, 필요가 없어졌을 때 메모리에서 사라지는 생명주기 싸이클이 존제한다. 아이폰 프로그램에서도 예외라고 할 수는 없다.


그림1. 아이폰 애플리케이션 생명주기.

애플리케이션의 생명 주기는 실행과 종료 사이에 발생하는 순차적인 이벤트들을 만들어낸다. 사용자는 아이폰 스크린의 아이콘을 선태하여 애플리케이션을 실행하게 된다. 이후에 시스템은 진행 상태를 보여주고 애플리케이션의 main 함수를 호출한다. 이 순간부터 초기화를 위한 작업들이 UIKit으로 넘어오는데, 애플리케이션의 UI를 불러오고 이벤트 루프를 준비한다. 이벤트 루프 과정에서 UIKit은 커스텀 객체로의 이벤트 전달과 애플리케이션에서 발생한 명령들을 처리하는 것을 조절하게 된다. 사용자가 프로그램을 종료하는 액션을 취하게 되면, UIKit을 통해서 애플리케이션에 알리고 종료가 진행된다.


애플리케이션 델리게이트.
애플리케이션 델리게이트(application delegate) 객체의 역할은 애플리케이션의 동작을 모니터링 하는 것이다. 델리게이트라함은 위임이라는 뜻을 가지고 있는데, 의미 그대로 메소드의 역할을 위임하는 것이라고 할 수 있다. 변수의 경우, 각 변수가 가지고 있는 값들을 어떤 특졍한 패턴, 함수에의해 변형되어, 개발자의 의도대로 결과 값을 얻을 수가 있다. 이런 특징적인 역할을 하는 함수(모듈, 객체, 메소드라고 정의할 수 있는)들을 특정한 조건이나, 의도를 가지고 묶음으로 만들어내 좀더 간편하게 사용하도록 하는 것이 델리게에트를 사용하는 목적이라고 할 수 있다. 또 한가지 델리게이트를 사용하는 이유는 UIApplication 과 같은 복잡한 객체를 상속하는 것을 피하고, 메소드를 재정의 하지 않음으로써 좀더 객체 지향적인 프로그래밍을 할 수 있도록 도와주게 된다.


그림2. 액션과 각 객체의 실행.

애플리케이션이 어떠한 액션을 만났을때, 그 액션에 맞는 객체의 메소드가 실행이 되게 된다. 이 객체는 객체에서 정의된 액션에 대해서만 행동을 하게 된다. 다양한 액션을 받아들이기 위해서는 그 액션에 대해서 정의를 해 주거나, 그 액션을 가지고 있는 상위 클래스를 상속 받아야 한다. 위 그림에서 action A 를 받아서 행동할 수 있는 것은 object A 뿐이다. action B 는 object B, action C 는 object C 로만 반응이 가능하다. 만약 action A 를 실행해야 하는 상황에서 action B 가 발생을 한다면 object A 는 적절한 대응을 할 수가 없다. action B 에 대응하기 위해서는 object B 가 상속받은 클래스를 동일하게 상속받아야 한다.


그림3. 델리게이트를 통한 확장.

이런 불필요한 자원의 낭비를 줄여주는 것이 델리게이트이다. 델리게이트는 메소드와 메소드를 이어주는 연결고리라고 할 수 있다. 필요한 메소드를 상속을 통한 확장이 아니라, 연결의 의미에서 전달만 하게 된다. 위의 그림처럼 action A, B, C 를 따로 따로 정의해서 사용하는 것이 아닌, object A, B, C 를 하나로 묶어주고, 연결해 줌으로써 좀더 다양한 action에 대응할 수 있는 유연성을 제공한다. 불필요한 상속을 줄여주는 것이다.


델리게이트의 선언.
델리게이트는 다음과 같이 선언되고, 사용할 준비가 된다.

ProjectNameViewController.h 파일
@Interface ProjectNameAppDelegate : NSObject <UIApplicationDelegate> {
        UIwindow *window;
        ProjectNameController *viewController;
}


ProjectNameViewController.m 파일
- (void)applicatoinDidFinishLaunching: (UIApplication *)application {
        // TODO something
}


델리게이트는 아이폰 프로그래밍에 있어서 뿐만아니라, 객체지향 프로그래밍에 있어서 중요한 요소임에 분명하다. 그 개념이 쉽게 이해가 되지 않을 수 있겠지만, 꼭 이해하고, 사용할 줄 알아야 한다.

Posted by seanhigher

댓글을 달아 주세요

버튼은 사용자들로 하여금 가장 간단하게 의도를 도출할 수 있는 좋은 도구이다. 사용자가 보고 있는 여러개의 버튼 중에서 단 하나 내가 원하는 것을 큭릭하기만 하면 된다.




Round Rect Button - Implements a button that intercepts touch events and sends an action message to a target object when it's tapped. You can set the title, image, and other appearance properties of a button. In addition, you can specify a different appearance for each button state.


버튼 애트리뷰트의 항목

▼ Button
Type : 버튼의 종류를 선택할 수 있다. 종류에 따라 다른 모양의 버튼이 나타나게 된다. Custom, Detail Disclosure Info light, Info Dark, Add Contact 중에 선택할 수 있다.
[ Title, Image, Background, Text Color, Shadow 의 항목에 대해서는 Default, Highlighted, selected, disabled 의 네가지 상태에 대해서 설정을 다르게 할 수 있다. ]
Title : 버튼에 나타날 텍스트를 표현한다.
Image : 버튼의 이미지를 나타낸다.
Background : 버튼을 배경으로 이미지를 나타낸다. 이미지는 원본의 비율을 유지하지만, Background 는 전체에 가득 차게 나타낸다.
Text Color : 텍스트의 색을 나타낸다.
Shadow : 그림자 색을 나타낸다.
Shadow : 그림자의 위치를 설정한다.
Drawing : Highlight Reverses Direction, Shows Touch On Highlight, Highlighted Adjusts Image, Disabled Adjusts Image 의 네가지 항목을 설정할 수 있다.
Font : 텍스트의 종류와 크기를 설정한다.
Line Breaks : 텍스트가 라벨의 영역을 넘어설 경우 어떻게 표현할 것인지를 설정한다. Clip 은 텍스트가 그대로 잘려지고, Character wrap 과 word wrap 은 문자 단위로, 단어단위로 텍스트가 표현된다. Truncate Head, Middle, Tail 은 줄임표를 앞, 중간, 뒷 등 표시하는 위치를 설정한다.
Content, Title, Image Edge Inset : 버튼 내의 내용, 타이틀, 이미지가 표시될 위치를 설정한다. Top, Bottom, Left, Right 는 각각 기준이 되는 위치를 말한다. Top 의 경우 위를 기준으로 숫자가 커질 수록 아래로 내려가게 된다.

▼ Control
Content : 각 오브젝트들의 정렬방식을 정할 수 있다. 그림을 보면 이해할 수 있으므로 보고 알맞은 것으로 정렬을 하면 된다. Highlighted, Selected, Enabled 의 추가적인 선택 사항들이 있다. 어떤 오브젝트들을 선택하고, 정렬에 포함할 것인지에 대해 결정하게 된다.

▼ View
Mode : 뷰에서 상속을 받아 갖고 있는 속성이기 때문에 이미지 뷰의 속성의 특징을 갖지만, 텍스트에서는 크게 영향을 주지 않는다.
Alpha : 이미지의 투명도를 조절하여 뒤에 있는 화면이 보이도록 한다. 숫자가 1 이하일 경우 투명도를 위한 연산을 해야 하기 때문에 필요할 때 이외에는 사용을 자제하도록 한다.
Background : 텍스트 배경 영역의 배경색을 지정한다. 특별한 이유가 없다면 투명상태로 유지한다.
Tag : 개발자가 각 컨트롤러를 구분하기 위해 임의의 태그를 줄 수 있다. 이 항목에 있어서는 IB 나 Xcode 등 애플리케이션이 임의로 변경할 수 없기 때문에 절대적인 구분이 가능하다.
Drawing : opaque 체크박스는 불투명 상태를 설정하게 된다. 알파값과의 차이점은 텍스트가 아닌 뷰에 직접 적용된다는 것이다. Hidden 체크박스는 컨트롤를 숨기는 역할을 한다. Clear Context Before Drawing 체크박스는 실제 컨트롤을 그릴 영역을 깨끗히 지운 후에 새로운 뷰를 그리게 한다. Clip Subviews 체크박스는 하위뷰가 있을 경우 어떻게 표현하지에 대해 설정한다. 체크할 경우 보여지지 않는 부분을 삭제 한 후에 이미지를 보여주게 되는데, 이것은 아이폰 OS 의 입장에서 삭제를 하지 않고 보여주는 것보다 더 자원을 소모하는 것이기 때문에 체크를 하지 않는 것이 기본 설정이다. Autoresize Subviews 체크박스는 뷰의 크기가 변경될 경우 포함되어 있는 하위 뷰의 크기도 변경되도록 한다.
Stretching : 표현하고자 하는 영역이 뷰보다 작을 경우 어떻게 확대할 것인지에 대한 설정을 할 수 있다. 이역시 텍스트에서는 크게 작용하지 않는다.
Interaction : User Interaction Enabled 는 사용자가 객체와 어떤 액션을 할 수 있도록 허용해준다. 이미지와 라벨의 경우는 대게 일반적인 정보만을 보여주기 대문에 이 옵션을 해제해 놓는다. 하지만, 버튼과 같이 액션이 필요할 경우엔 체크를 해 주어야 한다. Multiple Touch 멀티터치 이벤트를 허용할 것인가 이다. 멀티터치를 사용하지 않는다면 해제해 놓도록 한다.
Posted by seanhigher

댓글을 달아 주세요

스마트폰을 사용하는데 있어서 사용자의 의견을 텍스트의 형식으로 입력하는 기능은 필수적이라고 할 수 있다. 텍스트 필드는 사용자가 키보드를 사용하여 원하는 텍스트를 입력할 수 있는 효과적인 오브젝트이다.




Text Field Label - Displays a rounded rectangle that can contain editable text. When a user taps a text field, a keyboard appears; when a user taps Return in the keyboard, the keyboard disappears and the text field can handle the input in an application-specific way. UITextField supports overlay views to display additional information, such as a bookmarks icon. UITextField also provides a clear text control a user taps to erase the contents of the text field.


텍스트 필드 애트리뷰트의 항목.

▼ Text Field
Text : 화면에 표시될 텍스트를 입력한다. 보통은 View 화면에서 곧바로 입력하는것이 편하다.
Placeholder : 아무것도 입력하지 않은 상태일때 텍스트 필드 안에 표시되는 텍스트. 텍스트에 어떤 내용을 입력해야하는지 라벨을 사용할 공간이 부족할 경우 유용하게 사용할 수 있다.
Background : 배경 이미지를 선택할 수 있다. 'Resources' 폴더에 포함되어 있어야만 목록에서 선택이 가능하다.
Disable : Background 와 같이 텍스트의 배경 이미지를 선택한다. 차이점은 Background 가 텍스트 필드가 활성화 될때 나타나는 이미지이고, Disable 는 텍스트 필드가 활성화 되지 않은 일반적인 상황에서의 배경 이미지이다.
Alignment : 텍스트 필드에 쓰여지는 텍스트의 정렬 형태를 설정할 수 있다. 오른쪽의 네모는 컬러를 선택할 수 있다.
Border : 텍스트 필드의 표현 형식을 나타낸다. 일반적으로 가장 오른쪽에 있는 라운드 형태의 박스를 사용한다.
Clear Button : 텍스트를 입력할 때 삭제하는 버튼을 추가한다. Never appears 는 전혀 나타나지 않고. Appears while editing 는 텍스트를 입력하는 동안만, Appears unless editing 는 텍스트 입력을 마친 후에만 나타난다. Is always visible 는 입력할때, 입력한 후 계속 나타나있다. Clear When Editing Begins 의 항목을 체크면 텍스트 필드에 텍스트를 입력할 때마다 이전의 내용을 지우고, 새로 입력을 시작하게 된다.
Font : 텍스트의 서체와 크기를 설정한다.
Font Size : Adjust to fit 항목에 체크를 하고 라벨의 영역을 줄이면 Minimum 으로 정한 폰트 사이즈만큼 폰트의 크기가 줄어들게 된다. 체크를 하지 않을경우는 라벨의 영역을 줄여도 텍스트의 크기가 유지된다.
Text Input Traits : 텍스트를 입력할때의 모양과 키보드에 관한 설정을 하게 된다. Capitalize 는 대문자를 적용하는 방법을 설정한다. 단어별로, 문장별로, 모든 문자에 대문자를 적용할 수 있다. Correction은 자동 교정기능의 사용여부, Keyboard는 입력하고자 하는 내용에 따라 문자, 숫자, 특수문자 등 다양한 형식의 키보를 선택하여 나타나게 할 수 있다. Return Key 를 설정하면 'retun' 키 대신에 Go, google, jion 등 다른 문자가 나타나게 할 수 있다. 만약 비밀번호같이 누군가에게 감추고 싶은 정보라면 Secure 란에 체크를 하면 입력한 텍스트가 가려진다.

▼ Control
Content : 각 오브젝트들의 정렬방식을 정할 수 있다. 그림을 보면 이해할 수 있으므로 보고 알맞은 것으로 정렬을 하면 된다. Highlighted, Selected, Enabled 의 추가적인 선택 사항들이 있다. 어떤 오브젝트들을 선택하고, 정렬에 포함할 것인지에 대해 결정하게 된다.

▼ View
Mode : 뷰에서 상속을 받아 갖고 있는 속성이기 때문에 이미지 뷰의 속성의 특징을 갖지만, 텍스트에서는 크게 영향을 주지 않는다.
Alpha : 이미지의 투명도를 조절하여 뒤에 있는 화면이 보이도록 한다. 숫자가 1 이하일 경우 투명도를 위한 연산을 해야 하기 때문에 필요할 때 이외에는 사용을 자제하도록 한다.
Background : 텍스트 배경 영역의 배경색을 지정한다. 특별한 이유가 없다면 투명상태로 유지한다.
Tag : 개발자가 각 컨트롤러를 구분하기 위해 임의의 태그를 줄 수 있다. 이 항목에 있어서는 IB 나 Xcode 등 애플리케이션이 임의로 변경할 수 없기 때문에 절대적인 구분이 가능하다.
Drawing : opaque 체크박스는 불투명 상태를 설정하게 된다. 알파값과의 차이점은 텍스트가 아닌 뷰에 직접 적용된다는 것이다. Hidden 체크박스는 컨트롤를 숨기는 역할을 한다. Clear Context Before Drawing 체크박스는 실제 컨트롤을 그릴 영역을 깨끗히 지운 후에 새로운 뷰를 그리게 한다. Clip Subviews 체크박스는 하위뷰가 있을 경우 어떻게 표현하지에 대해 설정한다. 체크할 경우 보여지지 않는 부분을 삭제 한 후에 이미지를 보여주게 되는데, 이것은 아이폰 OS 의 입장에서 삭제를 하지 않고 보여주는 것보다 더 자원을 소모하는 것이기 때문에 체크를 하지 않는 것이 기본 설정이다. Autoresize Subviews 체크박스는 뷰의 크기가 변경될 경우 포함되어 있는 하위 뷰의 크기도 변경되도록 한다.
Stretching : 표현하고자 하는 영역이 뷰보다 작을 경우 어떻게 확대할 것인지에 대한 설정을 할 수 있다. 이역시 텍스트에서는 크게 작용하지 않는다.
Interaction : User Interaction Enabled 는 사용자가 객체와 어떤 액션을 할 수 있도록 허용해준다. 이미지와 라벨의 경우는 대게 일반적인 정보만을 보여주기 대문에 이 옵션을 해제해 놓는다. 하지만, 버튼과 같이 액션이 필요할 경우엔 체크를 해 주어야 한다. Multiple Touch 멀티터치 이벤트를 허용할 것인가 이다. 멀티터치를 사용하지 않는다면 해제해 놓도록 한다.

'Dev Center > iPhone Dev' 카테고리의 다른 글

델리게이트는 무엇일까?  (0) 2010.04.19
버튼 Attribute.  (0) 2010.04.18
텍스트 필드 Attribute.  (0) 2010.04.17
슬라이더로 표현하기.  (1) 2010.04.16
라벨 Attribute.  (0) 2010.04.15
이미지 뷰 Attribute.  (3) 2010.04.14
Posted by seanhigher

댓글을 달아 주세요

모바일 프로그램을 작성하다보면, 모바일 환경을 알아야 한다. 모바일 환경은 일반적인 데스크탑에서의 환경과는 다르게 한정된 자원을 이용해야 한다는 사실을 기억해야 한다. 그리고 그런 사실은 자원에서 뿐만 아니라, 인터페이스나, 디자인에서도 동일하게 적용된다.


New project.
새로운 프로젝트를 시작한다. 'View-based Application' 을 선택하고 프로젝트 이름은 'fiveSlider' 로 하였다. 이번에 만들게 될 애플리케이션은 여러개의 슬라이더가 있고, 라벨을 통하여 슬라이더의 수치를 표현해 주는 애플리케이션이다. 키보드로 입력하는 애플리케이션을 제작할때 처럼 어떤 형태의 애플리케이션이 될것인가에 대한 구상을 한다.


그림1. 프로젝트 구상.

프로젝트에 대한 구상을 마쳤다면 먼저 해야 할 것은 어떤 객체들을 아웃렛으로 선언하고, 어떤 액션을 가져야 하는지 생각해 보는 것이다. 'fiveSlider' 프로젝트에서는 슬라이더를 움직이면 왼쪽에 있는 숫자 라벨이 슬라이더의 내용에 맞게 변화되는 액션을 취하게 된다. 아주 간단한 기능을 가지고 있다. 여기서 변화가 있는 객체는 슬라이더 옆의 숫자 라벨과, 슬라이더이다. 숫자 라벨은 당연히 아웃렛을 선언을 해 주어야 한다. 하지만, 슬라이더는 그렇지 않다. 물론 아웃렛을 선언해도 작동한는것에는 문제가 없다. 하지만, 슬라이더 자체가 이미 아웃렛이 선언되어 있는 상태이기 때문에, 새로운 아웃렛을 선언하여 자원을 낭비할 필요가 없는 것이다.


아웃렛 선언과 액션 구현.
각 슬라이더의 내용을 표현하는 다섯개의 아웃렛을 'fiveSliderViewController.h' 파일에 선언을 한다. 선언한 아웃렛에는 프로퍼티를 함께 선언해 주어야 한다는 사실을 기억하자. 그리고 슬라이더의 움직임을 표현하기 위한 액션 메소드를 선언해 주어야 한다.

@interface fiveSliderViewController : UIViewController {
    UILabel *sliderLabel1;
    UILabel *sliderLabel2;
    UILabel *sliderLabel3;
    UILabel *sliderLabel4;
    UILabel *sliderLabel5;
}

@property (nonatomic, retain) IBOutlet UILabel *sliderLabel1;
@property (nonatomic, retain) IBOutlet UILabel *sliderLabel2;
@property (nonatomic, retain) IBOutlet UILabel *sliderLabel3;
@property (nonatomic, retain) IBOutlet UILabel *sliderLabel4;
@property (nonatomic, retain) IBOutlet UILabel *sliderLabel5;
- (IBAction)sliderControl1: (id)sender;
- (IBAction)sliderControl2: (id)sender;
- (IBAction)sliderControl3: (id)sender;
- (IBAction)sliderControl4: (id)sender;
- (IBAction)sliderControl5: (id)sender;
@end



'fiveSliderViewController.h' 파일의 선언을 마치고 'fiveSliderViewController.m' 파일을 수정해야 한다. 중간에 초록색으로 표현된 주석문들을 삭제하고, 아웃렛을 선언한 객체들에 대해 @synthesize 를 선언하고, 앞서 선언한 액션 메소드의 실제적인 행동을 정의한다.

#import "fiveSliderViewController.h"

@implementation fiveSliderViewController
@synthesize sliderLabel1;
@synthesize sliderLabel2;
@synthesize sliderLabel3;
@synthesize sliderLabel4;
@synthesize sliderLabel5;

-(IBAction)sliderControl1: (id)sender {     // 'sliderControl1' 의 액션 메소드 구현
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"%d", progressAsInt];
    sliderLabel1.text = newText;
    [newText release];
}

위의 소스에는 'sliderControl1' 에 대한 액션만 구현되어 있지만, 나머지 'sliderControl2 ~ 4' 에 대한 모든 액션이 구현되어 있어야 제대로 작동 하게 된다. '-(IBAction) sliderControl1: (id)sender { ... }' 의 부분을 복사, 붙여넣기한 후 'sliderControl1' 과 'sliderLabel1' 을 숫자만 바꾸어 주면 된다. 액션 메소드에서는 id 타입의 sender 라는 이름의 인자를 하나 가지게 된다. 이 sender는 여러개의 오브젝트에서 동일한 액션을 적용했을때, 각 오브젝트를 구분하는 역할을 하거나, 오브젝트에서 어떠한 값을 가지는지 전달하는 역할을 하게 된다. 'sliderControl' 액션 메소드에서는 슬라이더의 값을 전달하는 역할을 하고 있다. 액션 메소드 내에서는 id 타입으로 전달된 슬라이더의 값을 UISlider * 로 바꾸어준다. 이렇게하면 매번 sender 의 타입을 바꾸지 않아도 되는 장점이 있다. 그리고 슬라이더의 값에 0.5를 더해 반올림한 뒤 값을 int 타입으로 얻어내고, 이 값은 새로운 문자열로 생성하고, 레이블에 값을 전달한다. 레이블에 값을 전달하기 위해 사용된 NSString 타입의 newText 는 더이상 사용하지 않으므로 release 시킨다.


인터페이스 빌더로 화면 디자인 하기.
코드에 대한 부분이 마무리 되었다면 Resources 폴더의 'fiveSliderVierController.xib' 파일을 더블클릭하여 인터페이스 빌더를 실행한다. 구상했던데로 라벨들과, 슬라이더를 적절히 배치하여 모양을 만든다.


그림2. 인터페이스 디자인 만들기

슬라이더의 속성중에는 최고값과 최저값, 그리고 맨처음 애플리케이션이 실행될때의 표시 값을 설정할 수 있는데, 점수를 나타내는 것이기 때문에 '0 ~ 100' 으로 설정하고, 기본값은 '50' 으로 해 놓는다.


아웃렛과 액션 연결하기.
슬라이더의 값을 나타내는 라벨에 아웃렛을 연결하고, 각 슬라이더에 액션을 연결해 준다. 객체에 아웃렛을 연결하는 방법은 main 윈도우의 File's Owner 아이콘을 'ctrl' 버튼을 누른체로 클릭하여 아웃렛을 연결하고자 하는 객체로 마우스를 드래그 한다. 그러면 아웃렛이 선언된 객체들의 이름이 팝업으로 나타나는데, 알맞은 객체를 선택하면 된다.


그림3. 아웃렛 연결하기

아웃렛을 연결하는 또 하나의 방법은 'Connections' 윈도우를 이용하는 것이다. main 윈도우의 File's Owner 아이콘을 선택한후 'Connections' 윈도우를 띄운다. 가장 위를 보면 헤더 파일에 선언된 'Outlet' 의 목록을 볼 수 있는데, 연결하고자 하는 변수의 옆에 있는 원에 마우스를 가져가면 십자가 모양으로 바뀌는 것을 볼 수 있다. 이것을 끌어서 뷰 윈도우의 연결하고자 하는 객체에 가져다 놓으면 아웃렛이 연결 된다.


그림4. 액션 연결하기

액션을 연결하는 방법은 아웃렛을 연결하는 방법과 비슷하다. 뷰 윈도우에서 액션을 적용할 객체(슬라이더)를 선택하고, 'connections' 윈도우 를 띄운다. 슬라이더에 알맞는 액션은 'Value changed' 이다. 'Value changed' 의 오른쪽에 있는 원 부근에 마우스 커서를 가져가면 십자가 모양으로 바뀌는 것을 볼 수 있다. 이것을 쭉~ 끌어서 main 윈도우의 File's Owner 아이콘으로 가져간다. 이때 나타나는 팝업 메뉴에서 액션이 정의된 메소드를 선택한다. 잘못 연결하면 엉뚱한 숫자가 변할 수도 있다.


빌드하고 실뮬레이션 하기.
다시 Xcode 로 돌아가서 'Build and Run' 아이콘을 클릭하여 작성한 프로그램을 시뮬레이션 한다.



그림5. 'fiveSlider' 프로젝트 시뮬레이션

위 그림과 같이 슬라이더를 움직이면 옆의 숫자가 변하는 것을 볼 수 있을 것이다. 슬라이더는 비율이나, 정도를 수치로 표현할때 유용하게 쓸수 있는 라이브러리 객체이다.

'Dev Center > iPhone Dev' 카테고리의 다른 글

버튼 Attribute.  (0) 2010.04.18
텍스트 필드 Attribute.  (0) 2010.04.17
슬라이더로 표현하기.  (1) 2010.04.16
라벨 Attribute.  (0) 2010.04.15
이미지 뷰 Attribute.  (3) 2010.04.14
키보드로 입력해 보자!  (0) 2010.04.12
Posted by seanhigher

댓글을 달아 주세요

  1. 2011.06.12 15:08 rrr  댓글주소  수정/삭제  댓글쓰기

    감사합니다~ 잘알고가요!

일반적인 텍스트를 나타내기 위해서 사용하는 라이브러리이다. 정보를 표현하는 방법중에서 가장 정확하게 사용자에게 개발자의 의도를 표현하는 방법이 텍스트이다. 이런 텍스트를 나타내기 위해서 라벨의 사용은 필수적이다.




Label - Implements a read-only text view. A label can contain an arbitrary amount of text, but UILabel may shrink, wrap, or truncate the text, depending on the size of the bounding rectangle and properties you set. You can control the font, text color, alignment, highlighting, and shadowing of the text in the label.

라벨 애트리뷰트의 항목.

▼ Label

Text : 화면에 표시될 텍스트를 입력한다. 보통은 View 화면에서 곧바로 입력하는것이 편하다. 텍스트 안에 '\n' 문자를 포함할 경우 줄바꿈이 실행된다.
Baseline : 폰트의 크기를 변경할때 기준을 결정한다.
Line Breaks : 텍스트가 라벨의 영역을 넘어설 경우 어떻게 표현할 것인지를 설정한다. Clip 은 텍스트가 그대로 잘려지고, Character wrap 과 word wrap 은 문자 단위로, 단어단위로 텍스트가 표현된다. Truncate Head, Middle, Tail 은 줄임표를 앞, 중간, 뒷 등 표시하는 위치를 설정한다.
Layout : Algnment 는 텍스트를 정렬하는 방법을 나타낸다. #Lines 은 라벨에서 최대로 나타낼 수 있는 라인수를 나타낸다.
Font : 폰트를 설정할 수 있다. 버튼을 클릭하면 폰트를 설정하는 창이 나타난다.
Font Size : Adjust to fit 항목에 체크를 하고 라벨의 영역을 줄이면 Minimum 으로 정한 폰트 사이즈만큼 폰트의 크기가 줄어들게 된다. 체크를 하지 않을경우는 라벨의 영역을 줄여도 텍스트의 크기가 유지된다.
Color : 텍스트의 일반적인 색상을 설정한다.
Shadow : 그림자의 색을 설정한다. H.Offset 의 숫자가 커질 수록 텍스트와 그림자와의 거리가 가로방향으로 멀어지고, V.Offset 의 숫자가 커질 수록 세로방향으로 멀어진다. Enabled 항목을 체크해야지만 텍스트의 색상과 그림자가 설정된다.

▼ View
Mode : 뷰에서 상속을 받아 갖고 있는 속성이기 때문에 이미지 뷰의 속성의 특징을 갖지만, 텍스트에서는 크게 영향을 주지 않는다.
Alpha : 이미지의 투명도를 조절하여 뒤에 있는 화면이 보이도록 한다. 숫자가 1 이하일 경우 투명도를 위한 연산을 해야 하기 때문에 필요할 때 이외에는 사용을 자제하도록 한다.
Background : 텍스트 배경 영역의 배경색을 지정한다. 특별한 이유가 없다면 투명상태로 유지한다.
Tag : 개발자가 각 컨트롤러를 구분하기 위해 임의의 태그를 줄 수 있다. 이 항목에 있어서는 IB 나 Xcode 등 애플리케이션이 임의로 변경할 수 없기 때문에 절대적인 구분이 가능하다.
Drawing : opaque 체크박스는 불투명 상태를 설정하게 된다. 알파값과의 차이점은 텍스트가 아닌 뷰에 직접 적용된다는 것이다. Hidden 체크박스는 컨트롤를 숨기는 역할을 한다. Clear Context Before Drawing 체크박스는 실제 컨트롤을 그릴 영역을 깨끗히 지운 후에 새로운 뷰를 그리게 한다. Clip Subviews 체크박스는 하위뷰가 있을 경우 어떻게 표현하지에 대해 설정한다. 체크할 경우 보여지지 않는 부분을 삭제 한 후에 이미지를 보여주게 되는데, 이것은 아이폰 OS 의 입장에서 삭제를 하지 않고 보여주는 것보다 더 자원을 소모하는 것이기 때문에 체크를 하지 않는 것이 기본 설정이다. Autoresize Subviews 체크박스는 뷰의 크기가 변경될 경우 포함되어 있는 하위 뷰의 크기도 변경되도록 한다.
Stretching : 표현하고자 하는 영역이 뷰보다 작을 경우 어떻게 확대할 것인지에 대한 설정을 할 수 있다. 이역시 텍스트에서는 크게 작용하지 않는다.
Interaction : User Interaction Enabled 는 사용자가 객체와 어떤 액션을 할 수 있도록 허용해준다. 이미지와 라벨의 경우는 대게 일반적인 정보만을 보여주기 대문에 이 옵션을 해제해 놓는다. 하지만, 버튼과 같이 액션이 필요할 경우엔 체크를 해 주어야 한다. Multiple Touch 멀티터치 이벤트를 허용할 것인가 이다. 멀티터치를 사용하지 않는다면 해제해 놓도록 한다.

'Dev Center > iPhone Dev' 카테고리의 다른 글

텍스트 필드 Attribute.  (0) 2010.04.17
슬라이더로 표현하기.  (1) 2010.04.16
라벨 Attribute.  (0) 2010.04.15
이미지 뷰 Attribute.  (3) 2010.04.14
키보드로 입력해 보자!  (0) 2010.04.12
수시로 찾아보는 Class Reference Document.  (0) 2010.04.09
Posted by seanhigher

댓글을 달아 주세요

최근에 달린 댓글

글 보관함