최초 작성일 : 2010/09/26 02:03
1. View와 Control들의 역할
지난 시간까지 PC, 노트북, 모바일 기기 전체를 통틀어 가장 핵심이라고 할 수 있는
'데이터'를 관리하는 내용에 대해 코어 데이터를 이용하는 방법을 통해 알아보았습니다.
데이터의 '입력 -> 가공 -> 출력'은 모든 컴퓨팅 기기의 수행 업무에 대한 고전적인 정의라고도
할 수 있겠죠.
굳이 이와같은 말을 하지 않더라도 정확한 가공을 통한 정확한 정보의 출력은
디지털 기기에서 매우 중요한 일입니다.
하지만 이왕이면 다홍치마라고 정확한 정보가 출력되더라도 가급적이면 보기 좋게 출력되면
더 좋겠죠. 그래서 뷰와 컨트롤들을 잘 다루는 것 또한 중요하게 되는 것이구요.
당근 빠따인 말들은 집어 치우구요. 좀 더 기술적으로 말을 해보도록 하죠.
프로그래밍을 좀 해보신 분들은 MVC라는 말을 많이 들어보셨을 겁니다.
특히 객체 지향 프로그래밍에서는 이제는 너무나도 당연시되는 패턴이기도 하고
또 UI를 구성하는 대부분의 API가 바로 이 MVC 패턴을 기반으로 만들어져 있습니다.
물론 이 API를 이용한 개발자들의 코드도 MVC를 지키도록 노력하여 만들어 지고 있구요.
MVC는 곧 Model, View, Control의 첫 스펠링을 모은 용어입니다.
그러고 보니 3가지 모두 매우 익숙한 단어네요. Model이란 용어가 좀 걷돌기는 하지만
이전 글에서 코어 데이터를 다룰 때 분명 ManagedObjectModel이 있었죠.
그리고 View와 Control는 UI개발을 할 때 너무나 익숙한 용어들이구요. 게다가
이 글의 제목이기도 하네요…^^;;;
바로 그렇습니다. 꾸미지않고 직설적으로 연관을 지어보면 다음과 같습니다.
Model = 데이터
View = 데이터를 사용자에게 보여주는 화면
Control = 데이터의 입력이나 가공, 출력을 지시하는 객체들
가장 단순한 형태의 프로그램인 계산기를 생각해보도록 하죠.
액정 화면, 숫자키와 연산자 키, 그리고 계산을 할 수 있는 반도체 모듈만 있으면 가장 단순한
계산기가 하나 만들어질 것입니다. 이 계산기의 작동은 이렇습니다.
1. 사용자가 숫자키(Control) 10을 누릅니다.
2. 임시 저장공간에 10(Model)이 저장됩니다.
3. 액정 화면(View)에 10이 표시됩니다.
4. 사용자가 +키(Control)을 누릅니다.
5. 계산기는 연산의 종류를 기억합니다.
6. 사용자가 숫자키(Control) 5를 누릅니다.
7. 계산기는 10과 +연산을 할 대상으로 5를 기억합니다.
8. 사용자가 =키(Control)를 누릅니다.
9. 계산기는 연산을 진행하고 그 결과인 15를 액정 화면(View)에 표시합니다.
10. 사용자는 액정 화면(View)을 통해 결과를 확인합니다.
즉 숫자 및 연산자 키는 Control로 계산기에게 뭔가 지시를 하고 그 지시를 통해 변경된
사항을 View에게 알리도록 하여 View에 변경 사항이 반영되도록 합니다. 가장 복잡한
역할을 하네요.(그리고 우리가 흔히 Control이라 부르는 UI객체들은 대부분 View의 기능을
동시에 가지고 있는 객체들입니다. 따라서 원한다면 View없이 Control들만으로 화면을 구성하는
일도 얼마든지 가능합니다.)
Model에 해당하는 10과 5 및 이 둘의 +연산 결과인 15는 입력되고 가공되고 출력되는
데이터입니다. (물론 연산의 종류인 +도 데이터의 일종이긴 하나 좀 모호해서 확실하게
확인 가능한 숫자만 다룹니다.)
그리고 이러한 데이터들을 사용자가 시각적으로 확인할 수 있도록 View에 해당하는 액정 화면에
표시하도록 한 것입니다.
이 글을 작성하다가 문득 알게 된 내용인데요, iOS SDK에는 UIViewController라는 객체가
있습니다. 이름에 Controller가 들어있기지요. 비록 데이터와 연관은 없지만 외적 변화에 대한
내용을 View에 알려주어 View가 그 변화에 맞게 행동할 수 있도록 해줍니다.
다시 말해서 View를 가지고 있는 Control이죠.
위에서 UI객체들 중 Control들은 대부분 View를 가지고 있다('View 클래스를 상속받았다'가 좀더 정확한 표현이겠죠)고도 말했었는데요 이와같이 실제로 View와 Contro은 그 영역을 구분하기가
어려운 경우가 많습니다.
우리가 Interface Builder를 사용하든 혹은 사용하지 않고 코딩으로만 처리하든 화면 구성과
어떤 기능 수행을 위해 다양한 View들과 Control 등을 사용하게 됩니다.
위의 내용을 염두에 두신다면 이후 View와 Control들을 사용하고 배치하는데 어느 정도
도움이 되실 것입니다.
2. Interface Builder(이하 IB로 표기하겠습니다.) - 언제 쓰나?
최근 개발 툴들이 제공하는 기능 중에 편한 것 중 하나가 바로 UI를 WysWyg 방식으로
구성할 수 있도록 도구들을 제공한다는 점입니다.
필요한 객체들을 마우스를 통해 드래그 앤 드롭하여 개발자가 원하는 위치에 놓기만 하면
별다른 코딩 없이 화면을 멋지게 구성할 수 있습니다. Xcode에서는 그런 기능을 하는 툴이 바로
IB입니다. (IB에 대한 세부적인 내용이나 사용법은 본 글의 주제에서
벗어나므로 생략합니다.)
IB를 사용하게 되면 일일히 View나 Control의 좌표를 지정해준다든지 size를
설정한다든지 하는 번거로운 코딩을 하지 않아도 되기 때문에 작업 속도를 매우 빠르게 해줍니다.
하지만 언제든지 IB가 도움이 되는 것은 아닙니다.
예를들어 날짜별로 찍은 사진을 화면에 보여준다고 할 때 모든 날짜에 찍은 사진의 수가 일정한
것이 아니기 때문에 IB를 통해 ImageView를 배치하는 것이 불가능합니다.
이럴 경우에는 어쩔 수 없이 코딩을 통해 동적으로 ImageView를 생성해주는 수 밖에 없겠죠.
제가 IB를 사용하는 기준은 바로 이런 것입니다.
즉 화면상에 고정적인 객체들이 많이 필요하면 IB를 통해 화면을 먼저 설계를 한 후 동적으로
생성해야 할 객체들을 코딩을 통해 구현합니다.
또 이렇게도 씁니다. 전혀 .xib 파일이 필요 없고 모두 코딩을 통해 구현하게 되는 화면이지만
코딩을 하는 동안에는 화면 구성이 어떨지 실제로 볼 수도 없고 또 좌표를 확인하기도 쉽지
않기 때문에 우선 IB를 통해 화면 구성을 합니다. 그리고 각 객체들의 좌표를 확인한 후 그 값을
코딩에 이용합니다. 코딩이 끝나면 과감하게 .xib 파일을 지워버리죠…^^ 일종의 화면 설계 또는
프리젠테이션(키노트나 PPT같은) 용도로 사용을 하는 것이죠.
그러나 이런 경우에는 잘 사용을 안하게 됩니다.
1장에서도 말씀드린 바와 같이 Control이란 객체들은 상당히 복잡한 매커니즘을 가지고 있습니다.
때문에 개발자들의 코딩 대부분이 바로 이러한 Control들의 행동을 정의하는 것이라고 봐도
과언이 아닙니다.
이렇게 어차피 코딩이 많은 Control들을 화면에 구현하는 경우 그 갯수가
많아지면 많아질 수록 IBOutlet 설정하고 IBAction 설정하고 IB에서 코드와 객체 연결해주고…
이러한 과정이 오히려 더 번거로워질 수 있습니다. 그냥 컨트롤 생성하고 addTarget…메서드로
이벤트 지정해주는 것이 더 깔끔할 수 있죠. 이런 경우에도 IB를 사용하지 않고 작업을 하는 것이
더 좋을 수도 있을 것입니다. 운이 좋다면 for문을 통해 주루룩 생성할 수도 있죠…^^;;;
물론 이 것은 어디까지나 저의 경우입니다. 실제 IB를 어떻게 활용할 것인가 하는 것은
각 개발자분들이 경험을 통해 판단하는 것이 제일 정확할 것이라고 생각되네요.
3. View와 Control - 어떻게 배치할 것인가?
IB를 쓰건 안쓰건 UI를 구성하기 위해서는 각종 View들과 Control들을 배치를 해야 합니다.
하지만 여기서 중요한 것은 각종 View와 Control들의 수평적인 배치가 아니라
수직적인 배치입니다.
대다수의 프로그래밍 언어에서 UI 객체들은 Layer의 계층 구조를 이루고 있습니다.
포토샾에서의 Layer와 같은 개념으로 보시면 될 것입니다. 필요한 객체 이외의 부분은
투명 처리를 하여 하나 하나의 UI 구성 요소를 한겹 한겹 쌓아 올린 것이라고 보면 됩니다.
아래 그림은 UINavigationController Class Reference항목에 삽입되어있는 navigation controlle의
view 구성에 대한 그림입니다.
하나의 클래스 이렇게 중첩 구조로 되어있음은 물론 개발자들이 배치한 UI객체들도 모두
수직적인 위치를 갖게 되는 것입니다. HTML을 잘 아시는 분들은 z-index 속성을 아실 것입니다.
아쉽게도 IB에서는 z-index 처럼 수직적인 위치를 세세하게 지정할 수는 없습니다. 다만
가장 부모가 되는 View에서 sendSubviewToBack이나 bringSubviewToFront를 사용하여
가장 뒤로 혹은 가장 앞으로 가져오는 정도의 조절만을 할 수 있습니다.
만일 IB를 사용하였다면 이 작업을 보다 직관적으로 하실 수 있습니다.
두 번째 글 쯤에서 IB의 메인창에 대한 설명을 한 그림을 기억하시는지요?
다음과 같은 그림이었습니다.
위의 그림을 보시면 View에 배치된 컨트롤들의 목록이 보이실 것입니다. 바로 이 목록의
위치를 드래그 앤 드롭으로 이동하여 위치를 조절하시면 됩니다. 가장 위에 있는 컨트롤이
가장 아래(뒤쪽)에 있는 컨트롤이고 가장 아래 있는 컨트롤이 가장 위(앞쪽)에 있는 컨트롤입니다.
이 위치가 중요한 이유는 자칫 순서가 뒤바뀌어 단지 사진을 보여주는 이미지 뷰가 버튼 컨트롤을
가리면서 앞쪽에 위치하게 되면 버튼 컨트롤의 터치 다운 이벤트가 이미지 뷰에 막혀서 기능하지
않게 되기 때문입니다. 심한 경우는 그 모습도 보이지 않게 되죠…^^
같은 맥락에서 어떤 UI객체들을 서로 대등한 위치에 놓을 것인지 아니면 한 객체를 다른 객체의
하위에 놓을 것인지도 잘 고려해야 합니다.
예를들어 아래 그림과 같이 어떤 버튼을 눌렀을 경우 TextView와 관련된 영역이 확장되는 기능이
있다고 했을 때 만일 확장되는 영역의 모든 UI객체들(타이틀 바, 확장 버튼(▲, ▼), 날씨 버튼,
저장 버튼, UITextView 등)이 수평적으로 대등한 위치에 있게되면 확장/축소시 각각의 모든
객체들에 대해 좌표를 다시 설정을 해주어야 합니다. 하지만 만약 최 상위에 View를 하나 두고
UI객체들을 그 하위에 배치를 하게 되면 View, TextView, 타이틀 바 정도만 좌표와 사이즈를
수정하여 처리할 수 있게 되는 것입니다.
4. 요약
오늘은 화면 구서요소에 대한 원론적인 이야기와 함깨 지극히 개인적이지만 IB를 사용하면
좋은 경우와 안좋은 경우 그리고 UI 컨트롤들을 배치할 때 주의해야 할 사항들을 알아보았습니다.
워낙에 일반적이거나 개인적인 내용이다보니 몇줄로 요약하기도 쉽지 않네요. 주의점 하나만
더 언급하는 것으로 요약 부분을 마무리 하죠…^^;;;
일단 IBOutlet으로 설정하여 IB에서 배치한 객체와 연결을 하게 된 경우 이 객체에 대해서는
별도의 생성 처리를 해 주지 않아도 됩니다. IB에서 만들어진 객체에 대해 다시 코드상에서
alloc과 init관련 메서드를 통해 초기화를 하게 될 경우 IB에서 설정한 내용 정상적으로 반영이
안되는 경우가 생길 수 있습니다.
따라서 IB에서 만든 객체라면 단지 그 변화시에 반영해야 할 내용들, 예를들면 위치 변화, 크기
변화 혹은 일부 속성의 변화 등과 관련된 코딩만 해주시면 됩니다. 물론 dealloc에서 release는
해주시구요.
그리고 흔히 하시는 실수…IB에서 객체 만들어 놓고 코드상에서 IBOutlet 만들어놓고…
정작 연결 안시키는 실수…^^;;; 주의하세요~
5. 마무리
실제 소스를 분석하기 전에 우선 UI관련 객체들과 관련된 내용들의 일반적인 부분을 다루어
보았습니다. 여전히 시행착오를 거치고 있는 과정이다보니 실수가 적지 않을 것 같네요.
많은 조언 부탁드립니다.
다음 시간에는 위 내용을 바탕으로 제 앱인 iPhotoDiary의 메인 화면의 제작 과정을
분석해보도록 하겠습니다.
명절 후유증 잘 극복들 하시고 다음 시간에 뵙겠습니다.
'Development > iPhotoDiary(BabyPhotoDiary)' 카테고리의 다른 글
[옛 글] [실전 소스 분석] 8. 테이블 뷰 컨트롤러 써보기 - 1 (0) | 2013.07.18 |
---|---|
[옛 글] [실전 소스 분석] 7. 실제 소스 분석 - 메인 화면 (0) | 2013.07.18 |
[옛 글] [실전 소스 분석] 5. 코어 데이터의 끝 (0) | 2013.07.18 |
[옛 글] [실전 소스 분석] 4. 이제 Core Data좀 써보자! (0) | 2013.07.18 |
[옛 글] [실전 소스 분석] 3. 벌써 Core Data야??? (0) | 2013.07.18 |