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

카테고리

분류 전체보기 (161)
Blog srart (16)
Dev Center (94)
Real Life (13)
Mac life (21)
Naver life (17)
Total662,898
Today20
Yesterday18
첫번째로 작성한 'Hello world!' 프로젝트는 사용자가 할 수 있는 것이 아무것도 없다. 단지 화면에 나와 있는 텍스트만 뚫어져라 쳐다보고 있는 것 외에는... 휴대용 기기에서의 애플리케이션이라고 하면, 우선은 사용자와 반응하는 것이 중요하다. 사용자의 생각을 읽어서 자동으로 반응해 주는것이 가장 좋은 것이지만, 아직까지 기술이 그렇게 많이 발달하지 않았기때문에... 사용자가 뭔가 표현을 해주어야 반응을 하게 된다. 아이폰에 버튼을 만들고 버튼을 누르면, 뭔가 반응을 보일 것이다. 개발자가 잘 만들었다면...


어떤 모양으로 만들까?
누르면 반응하는 프로젝트를 개발하는데 있어서 가장 먼저 해야 할 것은 어떤 프로젝트를 만드냐이다. '누르면 반응하는 App'은 이미 뭔가 반응하게끔 만들어야 겠다는 의도와 목적이 들어 있기 때문에 그부분에 대해서는 고민할 필요가 없다. 그 다음으로는 어떠한 방식으로 그것을 구현할 것인가이다. 어떠한 방식으로 누르는 것을 표현할 수 있을까? 가장 간단하게 생각이 되는 것은 몇개의 버튼이 있는데, 그중 하나의 버튼을 누르면 그 버튼에 맞는 '무언가'가 실행이 되는 것이다. 아직 별 다른 기술이 없으므로 반응한는 '그 무언가'는 버튼에 맞는 텍스트가 출력되는 것으로 한다. 다시 정리를 하면...

(1) 화면중앙 부분에 세개의 버튼이 있다.(세개의 버튼은 1,2,3 이든, top, middle, bottom등...)
(2) 각 버튼에 알맞는 텍스트가 화면 아래에 출력된다.

매우 간단한 애플리케이션이지만, 이렇게 구체적인 계획을 세워 놓으면 프로젝트를 할때, 불필요한 고민을 하는 시간을 줄일 수 있다. 계획이 세워졌으므로 Xcode를 실행하고 'View-based Application' 프로젝트를 생성한다. 어떠한 이름을 하여도 상관은 없지만, 이해를 쉽게 하기 위해서 'FirstInteraction'으로 하도록 한다.


디자인먼저? 코딩먼저?
결론부터 말하자면, 디자인을 먼저하든, 코딩을 먼저하든 크게 상관이 없다. 어떠한 애플리케이션을 개발하더라도 이미 계획했던 것에 대해서 수정이 이루어지는 것은 불가피 하다. 코딩을 다 해놓은 상태에서 뷰를 디자인 하게 되면, 코딩에 맞추어서 디자인을 할 수 있지만, 생각하지 못했던 화면 제약이나, 표현상의 문제로 인해 코딩을 바꾸어야 하는 상황이 있을 수 있다. 또 디자인을 다 해 놓은 상태에서 기술적인 문제 때문에 기능을 제거한다던지, 다른 기능을 추가하는 등의 변경 사항이 발행하게 된다. 때문에 무엇을 먼저 하던 Xcode와 IB를 왔다갔다 해야 하는 것은 당연한 일이다. 하지만, 개인적으로는 디자인적인 문제보다는 기술적인 문제가 더 많이 발생하므로, 코딩을 먼저 완성한 후 디자인을 하는 것을 권유하고 싶다.


반응을 개발하기 위한 준비 작업.
반응을 애플리케이션에 포함시키기 위해서는 액션과 아웃렛이 사용된다. 액션은 반응을 위해 하는 어떠한 행위를 통해서 애플리케이션이 어떻게 반응해야 하는가에 대해서 말해주고, 아웃렛은 그러한 액션이 있다는 것을 IB와 xcode가 서로 알 수 있게끔 만들어준다.


그림1. FirstInteractionViewController.h 파일 수정

프로젝트에 액션과 아웃렛을 추가하기 위해서는 '프로젝트명ViewController.h 헤더파일에 선언해 주어야 한다. 반응이 일어나는 텍스트와 액션이 이루어지는 버튼을 사용할 것이기 때문에 다음과 같이 입력해 주면 된다.(굵은 글씨 부분이 추가해야 할 부분)

#import <UIKit/UIKit.h>

@interface FirstInteractionViewController : UIViewController {
    UILabel *labelText;
}

@property (nonatomic, retain) IBOutlet UILabel *labelText;
-(IBAction)buttonAction : (id)sender;

@end

Label 변수를 선언하고, 프로퍼티를 선언하여 수정이 가능한 메소드를 생성하였으며, 액션을 추가하여, 특정 액션으로부터의 접근이 가능하다. 헤더 파일에서 선언한 액션은 FirstInsteraction.m 파일에서 선언한 액션이 어떠한 행동을 할 것인가에 대해서 구현해 주어야 한다.


그림2. FirstInteractionViewController.m 파일 수정

컨트롤러 구현을 위한 파일인 '프로젝트명ViewController.m' 파일에는 개발에 자주 사용되는 메소드가 이미 구현이 되어 있다. 일부 코드들은 주석으로 처리 되어 있는데(초록색으로 되어 있는 부분), 이것들은 필요에 따라 주석을 해제하여 사용하거나, 삭제를 하여 작성하기도 한다. 'FirstInteraction' 프로젝트에서는 복잡한 메소드가 필요하지 않기때문에 주석된 부분을 다 삭제하고 코드를 간략화한다. 그리고 다음의 코드를 삽입한다.

#import "FirstInteractionViewController.h"

@implementation FirstInteractionViewController
@synthesize labelText;

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

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];   
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.labelText = nil;
}


- (void)dealloc {
    [labelText release];
    [super dealloc];
}

@end

기존에 생성되었던 코드보다 훨씬 더 간결해진것을 볼 수 있다. 굵은 글씨로 이루어진 부분의 소스코드를 살펴보면 생소한 것들이 많이 있다.

@synthesize labelText; - 헤더파일에서 'setText'변수를 프로퍼티로 선언하였다. 헤더파일에서의 선언은 접근자, 변경자 메소드에 대한 정의를 하고, 구현 파일에서의 sysnthesize 선언은 컴파일시에 컴파일러가 'setText'변수에 대한 접근자와 변경자 메소드를 생성해 준다. 개발자가 직접적으로 접근자와 변경자를 선언하지 않고, 구현하지 않아도 컴파일시에 자동으로 생성된다.
- (IBAction)buttonAction : (id) sender { } - 액션이 작용할때 하게 될 행동에 대해서 구현해 놓는 곳이다. 이 액션 메소드는 어떠한 버튼을 누르더라도 동일한 액션을 취하게 된다.
NSString *title = [sender titleForState: UIControlStateNormal]; - 액션이 작용하고 있는 버튼을 가르키는 sender에 할당된 값을 참조하여 어떤 버튼이 눌려지는지 알 수 있다. 이 메소드는 클릭된 버튼의 제목을 얻어 title 변수에 저장하기 위한, 미리 정의된 메소드를 사용하는 소스이다.
NSString *newText = [[NSString alloc] initWithFormat: @"%@ button pressed.", title]; - 이전에 저장된 title 변수에 'button pressed'라는 문자열을 추가한 새로운 문자열을 만든다. 새로운 변수의 이름은 'newText'가 된다.
labelText.text = newText; - Label로 선언된 변수에 입력을 받아 새롭게 정의된 newText의 값을 할당한다. 예문에서는 점표기법을 사용하였지만, [labelText setText:newText] 과 같은 방법으로도 표기할 수 있다.
[newText relese]; - 사용이 끝난 객체는 릴리즈시켜 자원의 낭비를 줄여야 한다. 모바일 프로그래밍의 경우, 일반적인 컴퓨터와는 다르게 자원의 규모나 성능이 작기때문에 최대한 효율적으로 사용해야 한다.
self.labelText = nil; - 클래스안의 아웃렛들은 viewDidUnload 메소드 안에서 nil 값으로 설정해 주어야 한다.
[labelText release]; - dealloc 메소드 안에서 아웃렛을 릴리즈 한다. 프로퍼티로 구현된 아웃렛이 retain의 속성을 가지기 때문에 릴리즈하여 자원의 낭비를 줄이는 일은 매우 중요하다.


외형 만들기.
소스코딩에 대한 부분을 마무리하였다면 멋들어진 외형을 만들어야 한다. 하지만, 아직은 그렇게 실력이 좋지 않으므로 계획에 있던데로 간단한 디자인으로 하도록 한다. 뷰를 편집하기 위해서는 'Groups & Files' 창에 있는 Resource 폴더의 'FirstInteractionViewController.xib' 파일을 더블클릭하면 나타나는 인터페이스빌더를 이용해야 한다.


그림3. 인터페이스 빌더가 실행된 화면

위 그림과 같이 인터페이스 빌더가 실행되면, 뷰 화면을 편집 한다. 왼쪽 라이브러리 윈도우에서 필요한 라이브러리 선택해서 오른쪽의 뷰 윈도우에 드래그를 해서 가져다 놓으면 된다. 각 객체는 크기를 마음대로 조절할 수 있으며, 객체들의 규칙적인 배치를 위해서 적절한 위치게 객체가 이동하게 되면, 파란점선의 가이드 라인이 자동으로 생성된다.


그림4. View 화면 편집

내용을 표시하게 될 label과 반응을 주게 될 세개의 버튼은 위의 그림과 같이 나란히 배치한다.(파란점선의 가이드 라인은 객체를 드래그 할때만 생겼다가 사라진다.) 객체를 나타내는 이름을 바꿔주기 위해서는 객체의 Label, button 등의 이름을 더블클릭하면 수정이 가능하다. button 객체의 이름을 각각 Top, Middle, Bottom 으로 바꾸어 주고 Label은 이름만 삭제한다. 맨처음 아무것도 누르지 않았을 때는 아무것도 나오지 않은 상태여야 하기 때문이다.


IB에서 아웃렛 선언해주기.
코딩과 디자인을 마무리 하였다면 이것을 서로에게 이어주는 작업이 필요하다. 각각의 객체들이 가지고 있는 작용들이 어떤 객체를 참조해야 하는지 직접적으로 이어주는 것이다.


그림5. 객체에 아웃렛 이어주기

객체에 아웃렛을 연결하기 위해서는 'FirstInteractionViewController.xib' 윈도우에 있는 'File's Owner' 아이콘에서부터 시작을 해야 한다. 컨트롤 키를 누른 상태에서 'File's Owner'아이콘을 클릭하여 드래그를 하면 위의 그림처럼 파란색의 선이 생기는 것을 보게 된다. 파란색의 선을 끌어당겨 Label이 있는 자리 근처로 가게 되면 Label 영역을 나타대는 사각형의 박스가 나타날 것이다. 이때 마우스의 버튼을 놓으면 작은 메뉴가 나타나게 되는데, 이전에 헤더파일에 지정하였던 아웃렛의 이름들이 나오는 것이다. 'labelText'를 선택하여 아웃렛을 연결해 준다.


객체에 액션 지정해 주기.
반응을 위한 버튼 객체에 액션을 지정해 주는 것은 아웃렛을 이어주는 것과 비슷하다. 코코아 프로그래밍에서는 두개의 작업이 거의 동일하게 이루어 졌지만, 아이폰 프로그래밍에서는 조금 다르게 작업을 해야 한다. 하지만, 정말 거의 비슷하다!


그림6. 객체에 액션 지정하기

오른쪽의 인스펙터 윈도우는 두번째에 있는 'Connections' 메뉴를 선택한다. 그리고 메인 뷰에서 액션을 지정하고자 하는 버튼(Top)을 선택하면 인스펙터 윈도우에 위와 같은 이벤트들이 나오게 된다. 다양한 이벤트들 중에서 버튼을 누르는 것과 가장 관련이 깊은 이벤트를 선택해야 한다. '반응하는 App' 은 버튼을 누르고 난 후 그 버튼의 종류에 따라 결과를 반환하게 되는것이기 때문에 'Touch up inside' 이벤트가 적절하다고 생각할 수 있다. 왜냐하면 선택하여 눌렀는데, 그 버튼이 마음에 들지 않아 손가락을 드래그하여 화면에서 땐다면 그것을 선택하지 않은 것이기 때문이다. 화면에서 가장 마지막에 손가락을 때었을때 버튼의 영역에 포함되어 있다면 그 버튼을 실행하고자 누른것으로 간주하는 것이다. 적절한 이벤트인 'Touch up inside'의 오른쪽에 있는 작은 원에 마우스를 갔다 놓으면 십자가 형태로 바뀌는 것을 볼 수 있다. 이 십자가를 끌어서 'FirstInteractionViewController.xib' 윈도우의 'File's Owner' 에 가져다 놓는다. 그러면 헤더파일에 선언되어 있는 액션 메소드의 리스트가 나타나게 된다. 'buttonAction'을 선택하여 액션을 이어준다. 나머지 두개의 버튼들도 동일한 작업을 거치면 모든 작업이 마무리 된다.


프로젝트 실행.
다시 Xcode로 돌아가서 'Build and Run' 버튼으로 프로젝트를 빌드하고 시뮬레이션 한다.


그림7. 프로젝트 시뮬레이션 화면

제대로 프로젝트가 완성되었다면 위의 화면과 같이 나올 것이다. 버튼만 세개가 있는 화면이 나온후에 버튼을 클릭하면 버튼에 맞는 텍스트가 화면 아래에 나오게 된다. 이제 사용자들의 의견을 수렴할 줄 아는 준비된 애플리케이션을 개발할 준비가 된것이다.

Posted by seanhigher

댓글을 달아 주세요

  1. 2010.07.31 02:06 쉬인  댓글주소  수정/삭제  댓글쓰기

    안녕하세요? 포스팅 내용이 정말 많은 도움이 되고 있습니다.
    이번 상호작용 편에서... 모두 제대로 한것 같은데 (커멘드+B 로 오류검사도 통과)
    정작 아이폰 시뮬레이터에서 버튼을 클릭하는 순간 어플이 종료되어 버립니다.

    혹시 이번에 업데이트 된 SDK를 사용해서 그런가요? 야심한 밤에 머리 쥐어뜯다가 글 남겨봅니다.
    알려주세요^^;;

    • 2010.08.02 09:54 신고 seanhigher  댓글주소  수정/삭제

      음... 그것만으로는 정확한 답을 드리기가... ^^;;
      하지만 제 경우에도 분명 똑같이 했음에도 불구하고 어플리케이션이 실행과 동시에 종료되는 경우가 있었는데... 뭔가 오타가 있거나, 연결을 제대로 해주지 않아서인 경우가 많더라구요... ^^;

  2. 2010.08.05 19:21 쉬인  댓글주소  수정/삭제  댓글쓰기

    앗 그렇군요
    한번 더 오타를 검사해봐야 겠습니다^^;
    좋은 정보 잘 보고있습니다.
    감사합니다 ㅎ

최근에 달린 댓글

글 보관함