시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

143
  • date post

    22-Jul-2016
  • Category

    Documents

  • view

    258
  • download

    0

description

데이브 마크, 잭 너팅, 제프 라마시 지음 | 유윤선 옮김 | 임베디드 & 모바일 시리즈 _ 015 | ISBN: 9788992939836 | 36,000원 | 2011년 06월 28일 발행 | 800쪽

Transcript of 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

Page 1: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발
Page 2: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발
Page 3: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

시작하세요!아이폰 4

프로그래밍

Page 4: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

iv

•목 차•

01장 __ 정글에 온 것을 환영한다 1이 책에 대한 소개 ...............................................................................................1

책에 필요한 도구 ................................................................................................2

개발 프로그램 옵션 .....................................................................................4

책을 이해하는 데 필요한 배경 지식 ...........................................................5

iOS 코딩의 차이점 .............................................................................................6

단 하나뿐인 활성화된 애플리케이션 .........................................................7

단 하나뿐인 창 .............................................................................................7

제한된 접근 ..................................................................................................7

제한된 응답 시간 .........................................................................................8

제한된 화면 크기 .........................................................................................8

제한된 시스템 자원 .....................................................................................8

가비지 컬렉션의 부재 .................................................................................9

코코아 터치의 고유 기능 ............................................................................9

다른 접근 방식 ...........................................................................................10

이 책에서 다루는 내용 .................................................................................... 10

개정판에서 달라진 점 ..................................................................................... 12

시작할 준비가 되었나? ................................................................................... 13

02장 __ 티키 신 달래기 15Xcode에서의 프로젝트 설정 .......................................................................... 15

Xcode 프로젝트 창 ....................................................................................19

Page 5: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

v

인터페이스 빌더의 소개 ................................................................................. 23

Nib 파일에 포함된 내용 ............................................................................25

뷰에 라벨 추가하기 ...................................................................................26

속성의 변경 ................................................................................................29

아이폰 다듬기 ― 화룡점정 ............................................................................ 31

컴파일과 실행 준비 완료 ..........................................................................34

정리하며... ........................................................................................................ 36

03장 __ 기본적인 상호작용의 처리 39모델-뷰-컨트롤러 패러다임 ........................................................................... 40

프로젝트의 생성 .............................................................................................. 41

뷰 컨트롤러의 생성 ......................................................................................... 41

아웃렛 .........................................................................................................43

액션 ...........................................................................................................44

뷰 컨트롤러에 액션과 아웃렛 추가 ..........................................................45

액션 메서드의 선언 ...................................................................................49

구현체 파일에 액션과 아웃렛 추가 ..........................................................49

애플리케이션 델리게이트의 활용 ................................................................. 55

MainWindow.xib 파일의 수정 ...................................................................... 59

Button_FunViewController.xib의 수정 ....................................................... 60

인터페이스 빌더에서의 뷰 생성 ...............................................................60

전체 연결 ....................................................................................................64

아웃렛의 연결 ............................................................................................64

Page 6: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

vi

액션의 지정 ................................................................................................66

결과 확인 ....................................................................................................68

내용 정리 .......................................................................................................... 68

04장 __ 더 재미있는 사용자 상호작용 71컨트롤로 가득 찬 화면 .................................................................................... 72

능동적 컨트롤과 수동적 컨트롤 .................................................................... 74

애플리케이션의 생성 ...................................................................................... 75

이미지 뷰와 텍스트 필드의 구현 ................................................................... 76

아웃렛에 대한 판단 ...................................................................................76

액션에 대한 판단 .......................................................................................78

이미지 뷰의 추가 .......................................................................................79

텍스트 필드의 추가 ...................................................................................84

두 번째 텍스트 필드에 대한 어트리뷰트 설정 ........................................89

아웃렛 연결 ................................................................................................90

키보드 닫기 ...................................................................................................... 90

Done을 탭할 때 키보드 닫기 ....................................................................91

배경을 터치할 때 키보드 닫기 ..................................................................92

슬라이더와 라벨 구현 ..................................................................................... 96

아웃렛과 액션에 대한 판단.......................................................................96

아웃렛과 액션의 추가 ...............................................................................97

슬라이더와 라벨의 추가 ...........................................................................98

액션과 아웃렛의 연결 .............................................................................100

스위치, 버튼, 분할 컨트롤의 구현 ............................................................... 100

아웃렛과 액션의 추가 .............................................................................101

스위치, 버튼, 분할 컨트롤의 추가 ..........................................................104

스위치 아웃렛과 액션의 연결 .................................................................106

버튼 추가 ..................................................................................................106

Page 7: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

vii

액션 시트와 경고창의 구현 .......................................................................... 108

액션 시트 델리게이트 메서드의 프로토콜 구현 선언 ..........................109

액션 시트 보여주기 .................................................................................109

버튼 꾸미기 .................................................................................................... 114

viewDidLoad 메서드의 활용..................................................................115

컨트롤의 상태 ..........................................................................................116

확장 가능 이미지 .....................................................................................116

메모리 관리 모범 시민 되기 ......................................................................... 117

결승선 통과하기 ............................................................................................ 118

05장 __ 자동 회전과 자동 크기 조절 121자동 회전의 역학 ........................................................................................... 122

Autosize 어트리뷰트를 활용한 회전 처리 .................................................. 124

회전 지원의 명시 .....................................................................................124

Autosize 어트리뷰트를 활용한 인터페이스 디자인 .............................126

사이즈 인스펙터의 Autosize 어트리뷰트 활용 .....................................128

버튼의 Autosize 설정 ..............................................................................130

기기 회전 시 뷰 구조의 조정 ........................................................................ 131

아웃렛의 선언과 연결 .............................................................................133

회전 시 버튼 움직이기 ............................................................................134

뷰 대체하기 .................................................................................................... 136

아웃렛과 액션에 대한 판단.....................................................................138

액션과 아웃렛의 선언 .............................................................................138

두 개의 뷰 디자인 ....................................................................................139

뷰 대체와 액션 구현 ................................................................................141

이곳에서 빠져나가기 .................................................................................... 144

Page 8: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

viii

06장 __ 멀티 뷰 애플리케이션 147멀티 뷰 애플리케이션의 공통적인 형태 ..................................................... 147

멀티 뷰 애플리케이션의 아키텍처 .............................................................. 152

루트 컨트롤러 ..........................................................................................154

콘텐츠 뷰의 해부 .....................................................................................155

View Switcher 애플리케이션의 개발 .......................................................... 155

뷰 컨트롤러와 Nib 파일의 생성 .............................................................157

애플리케이션 델리게이트의 수정 ..........................................................160 SwitchViewController.h .........................................................................162

뷰 컨트롤러의 추가 .................................................................................162

툴 바를 활용한 뷰 개발 ...........................................................................166

루트 뷰 컨트롤러의 작성 ........................................................................168

콘텐츠 뷰의 구현 .....................................................................................174

화면 전환 애니메이션 .............................................................................177

스위치를 내릴 시간 ....................................................................................... 181

07장 __ 탭 바와 피커 183Pickers 애플리케이션 ................................................................................... 184

델리게이트와 데이터 소스 ........................................................................... 188

탭 바 프레임워크의 설정 .............................................................................. 189

파일 생성 ..................................................................................................190

루트 뷰 컨트롤러의 추가 ........................................................................191

MainWindow.xib의 수정........................................................................193

아웃렛 연결과 실행 .................................................................................200

데이트 피커의 구현 ....................................................................................... 200

단일 컴포넌트 피커의 구현 .......................................................................... 204

아웃렛과 액션의 선언 .............................................................................204

뷰 개발 ......................................................................................................205

데이터 소스와 델리게이트로 활용할 컨트롤러의 구현 .......................206

Page 9: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

ix

멀티컴포넌트 피커의 구현 ........................................................................... 211

아웃렛과 액션의 선언 .............................................................................212

뷰의 개발 ..................................................................................................212

컨트롤러의 구현 ......................................................................................213

의존 컴포넌트의 구현 ................................................................................... 217

커스텀 피커를 활용한 간단한 게임 개발 .................................................... 225

컨트롤러 헤더 파일의 작성.....................................................................225

뷰의 개발 ..................................................................................................226

이미지 자원의 추가 .................................................................................227

컨트롤러의 구현 ......................................................................................228

마지막 디테일 ..........................................................................................235

Audio Toolbox 프레임워크의 연결 .......................................................241

마지막 스핀 .................................................................................................... 242

08장 __ 테이블 뷰의 기본 개념 245테이블 뷰의 기본 ........................................................................................... 246

테이블 뷰와 테이블 뷰 셀 .......................................................................246

그룹 테이블과 일반 테이블.....................................................................248

간단한 테이블의 구현 ................................................................................... 249

뷰 디자인 ..................................................................................................249

컨트롤러의 작성 ......................................................................................250

이미지의 추가 ..........................................................................................255

테이블 뷰의 셀 스타일 활용....................................................................257

들여쓰기 수준의 설정 .............................................................................260

행 선택값의 처리 .....................................................................................261

폰트 크기와 행 크기의 수정....................................................................263

테이블 뷰 셀의 커스터마이징 ...................................................................... 266

테이블 뷰 셀에 하위 뷰 추가 ...................................................................266

Nib으로부터의 UITableViewCell 로드 .................................................272

Page 10: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

x

그룹 섹션과 인덱스 섹션 .............................................................................. 278

뷰의 개발 ..................................................................................................278

데이터 불러오기 ......................................................................................279

컨트롤러의 구현 ......................................................................................279

인덱스의 추가 ..........................................................................................284

검색 바의 구현 ............................................................................................... 285

데이터 구조에 대한 생각 정리 ................................................................286

수정 가능 객체의 깊은 복사본 ................................................................287

컨트롤러 헤더 파일의 업데이트 .............................................................290

뷰의 수정 ..................................................................................................291

컨트롤러 구현체의 수정 .........................................................................293

한 테이블 위에 올려놓고 모두 정리하기 .................................................... 309

09장 __ 내비게이션 컨트롤러와 테이블 뷰 311내비게이션 컨트롤러 .................................................................................... 312

스택이란? .................................................................................................312

컨트롤러의 스택 ......................................................................................313

6개 영역으로 구성된 계층적 애플리케이션 Nav ...................................... 314

하위 컨트롤러 살펴보기 .........................................................................314

Nav 애플리케이션의 골격 ......................................................................320

첫 번째 하위 컨트롤러: 더 보기 버튼 뷰 ................................................331

두 번째 하위 컨트롤러: 체크리스트 .......................................................341

세 번째 하위 컨트롤러: 테이블 행 내의 컨트롤 ....................................348

네 번째 하위 컨트롤러: 이동 가능한 행 .................................................357

다섯 번째 하위 컨트롤러: 삭제 가능한 행 .............................................366

여섯 번째 하위 컨트롤러: 편집 가능한 상세 영역 ................................373

그런데 남은 작업이 한 개 더 있다. . . .....................................................399

결승선 통과하기 ............................................................................................ 403

Page 11: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xi

10장 __ 아이패드에 대한 고려 사항 405분할 뷰와 팝 오버 .......................................................................................... 405

분할 뷰 프로젝트의 생성 ........................................................................407

구조를 정의한 Xib ...................................................................................409

기능을 정의한 코드 .................................................................................411

대통령님이 오십니다 .................................................................................... 420

커스텀 팝오버의 생성 .............................................................................426

아이패드 마무리 ............................................................................................ 434

11장 __ 애플리케이션 설정과 사용자 기본값 437설정 번들 이해하기 ....................................................................................... 437

AppSettings 애플리케이션........................................................................... 439

프로젝트의 생성 ......................................................................................443

설정 번들의 활용 .....................................................................................444

애플리케이션에서 설정 읽기 ..................................................................459

애플리케이션 내에서의 기본값 수정 .....................................................465

실제처럼 만들기 ......................................................................................469

스코티, 날 전송해줘 ...................................................................................... 473

12장 __ 데이터 영속성의 기본 475애플리케이션의 샌드박스 ............................................................................ 476

Documents 디렉터리 접근 .....................................................................477

tmp 디렉터리 접근 ..................................................................................478

파일 저장 전략 ............................................................................................... 479

단일 파일을 통한 영속화 ........................................................................479

여러 파일을 통한 영속화 ........................................................................479

프로퍼티 리스트의 활용 ............................................................................... 480

프로퍼티 리스트의 직렬화......................................................................480

Page 12: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xii

데이터 영속성을 활용한 첫 번째 애플리케이션 ...................................482

모델 객체 아카이빙 ....................................................................................... 489

NSCoding 따르기 ....................................................................................489

NSCopying의 구현 ..................................................................................491

데이터 객체의 아카이빙과 아카이빙 해제 ............................................492

아카이빙 애플리케이션 .........................................................................493

iOS의 임베디드 SQLite3 활용 ..................................................................... 499

데이터베이스의 생성과 열기 ..................................................................500

바인드 변수의 활용 .................................................................................501

SQLite3 애플리케이션 ............................................................................503

코어 데이터의 활용 ....................................................................................... 511

엔티티와 관리 객체 .................................................................................513

코어 데이터 애플리케이션......................................................................518

영구적인 보상 ................................................................................................ 531

13장 __ 그랜드 센트럴 디스패치, 백그라운드 처리, 그리고 여러분 533

그랜드 센트럴 디스패치 ............................................................................... 533

SlowWorker의 소개 ...................................................................................... 534

스레딩의 기본 ................................................................................................ 539

작업 단위 ........................................................................................................ 540

GCD: 저수준 큐 ............................................................................................ 541

블록헤드 되기 ..........................................................................................541

SlowWorker의 개선.................................................................................543

백그라운드 처리 ............................................................................................ 550

애플리케이션 생명 주기 .........................................................................551

상태 변경 알림 .........................................................................................552

State Lab 애플리케이션의 생성 .............................................................554

Page 13: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xiii

실행 상태 살펴보기 .................................................................................555

실행 상태 변화의 활용 ............................................................................557

비활성 상태의 처리 .................................................................................559

백그라운드 상태의 처리 .........................................................................565

그랜드 센트럴 디스패치, 통신 끝! ............................................................... 576

14장 __ 쿼츠와 오픈GL을 활용한 드로잉 579그래픽 세상의 두 가지 뷰 ............................................................................. 580

드로잉에 대한 쿼츠의 접근 방식 ................................................................. 581

쿼츠2D의 그래픽 컨텍스트 ....................................................................581

좌표계 .......................................................................................................582

색상의 지정 ..............................................................................................584

컨텍스트 내에서의 이미지 드로잉 .........................................................587

도형 그리기: 다각형, 선, 곡선.................................................................587

쿼츠2D 툴 예제 - 패턴, 그라이언트, 점선 패턴 ....................................588

QuartzFun 애플리케이션 ............................................................................ 589

QuartzFun 애플리케이션의 설정 ..........................................................589

쿼츠 드로잉 코드의 추가 ........................................................................602

QuartzFun 애플리케이션의 최적화 ......................................................609

GLFun 애플리케이션 ................................................................................... 613

GLFun 애플리케이션의 설정 .................................................................614

오픈GL을 활용한 드로잉 ........................................................................616

GLFun 애플리케이션의 마무리 .............................................................626

끝이 가까워지고 있다. .................................................................................. 627

15장 __ 탭, 터치, 제스처 629멀티터치 관련 용어 ....................................................................................... 630

리스폰더 체인 ................................................................................................ 631

Page 14: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xiv

리스폰더 체인을 따라 올라가기 .............................................................632

리스폰더 체인을 활용한 이벤트 전달 ....................................................633

멀티터치 아키텍처 ........................................................................................ 634

터치 코드의 작성 위치 ............................................................................634

네 가지 터치 알림 메서드 .......................................................................634

터치의 감지 .................................................................................................... 636

TouchExplorer 애플리케이션의 개발 ...................................................637

TouchExplorer의 실행 ............................................................................640

스와이프의 감지 ............................................................................................ 641

Swipes 애플리케이션의 개발 .................................................................642

자동 제스처 인식 기능의 활용 ................................................................645

다중 스와이프의 구현 .............................................................................647

멀티 탭의 감지 ............................................................................................... 649

핀치의 감지 .................................................................................................... 656

커스텀 제스처의 생성 및 활용 ..................................................................... 659

체크 표시 제스처의 정의 ........................................................................660

체크 표시 제스처의 뷰 적용....................................................................664

저기요? 확인 부탁해요! ................................................................................ 665

16장 __ 여기는 어디? 코어 로케이션을 활용한 길 찾기 667위치 관리자 .................................................................................................... 668

원하는 정확도의 설정 .............................................................................668

거리 필터의 설정 .....................................................................................669

위치 관리자의 사용 시작 .............................................................................. 670

위치 관리자의 현명한 활용법 .................................................................670

위치 관리자 델리게이트 ............................................................................... 670

위치 업데이트 받기 .................................................................................670

CLLocation을 활용한 위도와 경도 파악 ...............................................671

에러 알림 ..................................................................................................673

Page 15: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xv

코어 로케이션의 활용 ................................................................................... 674

위치 관리자 업데이트 .............................................................................679

이동 거리의 판단 .....................................................................................680

이제 어디로 갈까? ......................................................................................... 681

17장 __ 야호! 자이로와 가속도계! 683가속도계 물리학 ............................................................................................ 683

회전을 잊지 말자 ........................................................................................... 684

코어 모션과 모션 관리자 .............................................................................. 685

이벤트 기반의 모션 .................................................................................686

적극적인 모션 접근 .................................................................................693

가속도계의 결과 ......................................................................................696

흔들림 감지 .................................................................................................... 696

흔들림 감지 내장 기능 ............................................................................699

흔들어서 깨뜨리기 ..................................................................................699

가속도계를 활용한 방향 제어 ...................................................................... 706

구슬 굴리기 ..............................................................................................707

BallView의 작성 ......................................................................................709

구슬의 움직임 계산 .................................................................................713

구슬이 굴러 가듯이 다음 장으로 ................................................................. 717

18장 __ 아이폰 카메라와 사진 라이브러리 719이미지 피커와 UIImagePickerController의 활용 ..................................... 720

이미지 피커 컨트롤러 델리게이트의 구현 ................................................. 722

카메라와 사진 라이브러리의 길거리 테스트 ............................................. 724

인터페이스 디자인 ..................................................................................726

카메라 뷰 컨트롤러의 구현.....................................................................726

식은 죽 먹기!.................................................................................................. 732

Page 16: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xvi

19장 __ 애플리케이션의 지역화 735지역화 아키텍처 ............................................................................................ 736

문자열 파일 .................................................................................................... 737

문자열 파일의 내용 .................................................................................738

지역화된 문자열 매크로 .........................................................................739

현실 세계의 iOS: 애플리케이션의 지역화 .................................................. 740

LocalizeMe 애플리케이션의 설정 .........................................................740

LocalizeMe의 테스트 ..............................................................................745

Nib 파일의 지역화 ...................................................................................746

이미지의 지역화 ......................................................................................750

문자열 파일의 생성과 지역화 .................................................................752

애플리케이션 표시 이름의 지역화 .........................................................755

안녕, 또 만나요 .............................................................................................. 756

20장 __ 이제 어디로? 759문제에서 빠져나오기 .................................................................................... 759

애플의 문서 ..............................................................................................760

메일링 목록 ..............................................................................................760

토론 포럼 ..................................................................................................761

웹사이트 ...................................................................................................762

블로그 .......................................................................................................763

컨퍼런스 ...................................................................................................764

저자 트위터 팔로우 .................................................................................764

작별 인사 ........................................................................................................ 765

찾아보기..............................................................................766

Page 17: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xvii

데닌, 다니엘, 켈리, 라이언, LFU4FRNMWWA에게

- 데이브

웨로니카, 헨리에타, 도로티에게

- 잭

내 인생에서 가장 중요한 사람인 아내와 아이들에게

- 제프

Page 18: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xviii

•옮긴이 글•

이 책은 이미 한국 독자들에게 잘 알려진 『시작하세요 아이폰 3 프로그래밍』의 개정판이다. 이

번 개정판에서는 iOS 4 SDK에 맞게 프로젝트 코드를 조금씩 수정하고, 새로운 장을 몇 개 추가

했으며, 설명도 보강했다. 역자는 이 책을 통해 처음 개발을 시작하는 독자들을 배려해 번역 과

정에서 Xcode 4 기준으로 책의 모든 설명을 수정했다. 이 책이 iOS 프로그래밍을 처음 시작하는

독자는 물론 iOS 4 SDK의 새롭고 강력한 기능을 활용해 애플리케이션을 개발하고자 하는 기존

개발자들에게도 큰 도움이 되기를 바란다.

이 책에서 다루는 내용

이 책은 프로그래밍 도구 설치부터 iOS SDK의 최신 기능인 다중 스레딩 프로그래밍에 이르기까

지 iOS 프로그래밍과 관련한 모든 내용을 상세히 다룬다. 특별히 개정판에서는 아이패드의 사용

자 경험을 고려한 애플리케이션 개발 방법과 다중 스레딩을 활용한 고급 프로그래밍 기법을 위

해 별도로 장을 할애하고 있다. 이 책을 통해 독자들은 iOS 프로그래밍의 기본 원리를 쉽게 익힐

수 있음은 물론, 어렵게만 보였던 테이블 뷰나 내비게이션 컨트롤러의 동작 원리를 배울 수 있고,

저자들이 계속해서 강조하는 '메모리 관리 모범 시민 되기' 원칙에 따라 메모리 관리를 위한 코딩

습관을 몸에 익힐 수 있을 것이다. 이 책은 장과 장의 예제가 별도로 작성돼 있으므로 특정 주제

를 학습하고자 하는 독자라면 언제든 해당 장을 펼쳐서 내용을 살펴볼 수 있다. 특별히 이 책의

이전 버전을 갖고 있는 독자라면 아이패드의 사용자 경험에 대해 다루는 10장과, 다중 스레드에

대해 다루는 13장을 먼저 읽어보면 많은 도움이 될 것이다.

이 책의 장점은 저자들의 혜안이 담겨 있다는 것이다. 이 책을 통해 독자들은 iOS 프로그래밍

의 모범 개발 방식(best practice)을 자연스럽게 익힐 수 있다. 예를 들어 속성으로 사용할 내부

변수를 명시적으로 선언하는 습관이나 #pragma를 활용한 코드 구조화, 기저 컨트롤러의 구현

과 컨트롤러 상속을 통한 코드 재사용 등은 저자들이 주는 이런 혜안 중 일부에 지나지 않는다.

Page 19: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xix

이 책의 대상 독자

이 책은 단순히 iOS 4 SDK에서 추가된 내용뿐 아니라 iOS 프로그래밍 전반을 다루고 있으므로

기존 개발자뿐 아니라 새로 iOS 프로그래밍에 입문하는 독자들이 읽기에도 좋은 책이다. 아울

러 이 책의 이전 버전을 갖고 있는 독자라 하더라도 책의 내용 설명 중 여러 곳이 수정됐으므로

이 책의 내용을 처음부터 끝까지 읽어볼 것을 추천한다.

감사의 글

우선 역자를 믿고 이 책의 번역을 의뢰해주신 위키북스 박찬규 사장님께 감사드린다. 또 교정을

담당해주신 김윤래 편집장 님께도 감사드린다. 이 분들이 없었다면 이렇게 좋은 책이 아직까지

빛을 보지 못했을 것이다. 또 항상 사랑하는 가족, 그리고 하나님께도 감사드린다.

- 유윤선

Page 20: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xx

•저자 소개•

데이브 마크 (Dave Mark)

데이브 마크는 오랫동안 맥 개발자이자 저자로 일하고 있으며 맥과 iOS

개발과 관련한 다양한 책을 저술했다. 저서로는 ‘Beginning iPhone 3

Development(Apress, 2009)’, ‘More iPhone 3 Development(Apress,

2010)’ 등이 있다. 데이브는 iOS와 안드로이드 개발 업체인 MartianCra�

의 대표다. 그는 아내와 세 아이와 함께 버지니아에서 살고 있다.

잭 너팅 (Jack Nutting)

잭 너팅은 코코아를 코코아라고 부르기 전부터 코코아를 사용했다. 잭

은 코코아와 코코아의 전신을 활용해 게임, 그래픽 디자인, 온라인 디지

털 배포, 텔레콤, 금융, 출판, 여행 등 다양한 산업 분야의 애플리케이션

을 개발했다. 잭은 오브젝티브-C와 코코아 프레임워크의 열렬한 지지자

다. 잭은 ‘Learn Cocoa on the Mac(Apress, 2010)’과 ‘Beginning iPad

Development for iPhone Developers(Apress, 2010)’의 주요 저자다. 잭은 이따금씩 http://

www.nuthole.com에 블로그 글을 남긴다.

제프 라마시 (Jeff LaMarche)

제프 라마시는 20년 이상의 프로그래밍 경험을 지닌 맥과 iOS 개발자다. 제

프는 ‘Beginning iPhone 3 Development(Apress, 2009)’, ‘More iPhone 3

Development(Apress, 2010)’, ‘Learn Cocoa on the Mac(Apress, 2010)’ 등

다양한 iOS와 맥 관련 책을 저술했다. 제프도 iOS와 안드로이드 개발 업체

인 MartianCra�의 대표다. 또 제프는 많은 사람이 구독하는 자신의 블로

그인 http://iphonedevelopment.blogspot.com에 iOS 개발에 대한 내용을 쓰고 있다.

Page 21: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xxi

•기술 감수자 소개•

마크 달림플 (Mark Dalrymple)

마크 달림플은 맥과 유닉스 프로그래밍에 오랜 경험을 지니고 있으며 크

로스 플랫폼 툴킷, 인터넷 배포 툴, 고성능 웹 서버, 최종 사용자를 대상

으로 한 데스크톱 애플리케이션 개발 분야 등에 종사하고 있다. 마크는

'Advanced Mac OS X Programming(Big Nerd Ranch, 2005)'와 'Learn

Objective-C on the Mac(Apress, 2009)'의 주요 저자이기도 하다. 여가 시

간에 마크는 트롬본과 바순을 불기도 하고 풍선으로 동물을 만들기도 한다.

Page 22: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xxii

•감사의 글•

이 책은 항상 힘이 되고, 친절하며 현명하기까지 한 가족과 친구, 그 외 도움을 주신 분들이 없었

다면 세상에 나올 수 없었을 것이다. 먼저 테리, 웨로니카, 데닌에게 감사드린다. 우리 저자들이

이 책의 집필로 수고하는 동안 이분들은 나머지 가사 일을 모두 책임져 주었다. 이번 책을 쓰느라

저자들은 아주 오랜 시간 동안 집필에 몰두해야 했지만 저자들의 아내들은 한 번도 불평하지 않

았다. 우리는 정말 행복한 남자들이다.

또 이 책은 Apress 출판사의 훌륭한 직원들이 없었다면 쓸 수 없었을 것이다. 클래이 안드레스

는 우리 저자들을 제일 처음 Apress로 안내했고 이 책을 업어 키우다시피 했다. 도미니크 쉐이크

셰프트는 항상 미소를 띤 채 저자들의 불만 사항을 모두 해결해줬고 이 책을 더 좋게 만들 수 있

는 해결책을 매번 제시해줬다. 이 책의 편집자인 켈리 모리츠는 저항할 수 없는 힘으로 저자들의

느린 집필 활동을 독려해줬다. 개발 편집자인 톰 웰시는 집필 과정에서 훌륭한 피드백을 통해 많

은 도움을 주었다. 두 편집자 덕분에 책은 올바른 속도로 올바른 방향을 따라 집필될 수 있었다.

카피 에디터인 마를린 스미스와 킴 윔프셋 덕분에 즐거운 작업을 할 수 있었다. 제프리 페퍼, 프랭

크 맥거킨, 브리짓 더피, 그 외 Apress 출판사의 제작팀은 모든 작업을 한데 어우러지게 해서 멋

진 작품을 만들어줬다. 레오 쿠엘라, 다일란 우터스, 제프 스톤필드는 이 책의 마케팅을 담당해

줬다. Apress의 모든 직원들에게 감사, 또 감사한다.

또 이 책의 기술 리뷰를 담당해준 마크 달림플에게도 특별히 감사를 드리고 싶다. 혜안이 가득

한 피드백을 주는 것 외에 마크는 이 책의 모든 코드를 테스트해줬고 우리 저자들이 정도를 따라

책을 집필할 수 있게 도와줬다. 마크에게 다시 한 번 감사한다.

끝으로 아버지가 열심히 일하는 동안 기꺼이 참아준 아이들에게 감사 인사를 전한다. 매디, 위

니, 이안, 카이, 헨리에타, 도로티, 다니엘, 켈리, 라이언, 이 책은 너희들을 위한 책이란다.

Page 23: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

xxiii

•서 문•

이 책의 이전 버전인 『시작하세요 아이폰 3 프로그래밍』의 서문은 이렇게 시작했다. "얼마나 놀

라운 여행인가!" 사실 맞는 말이다. 우리는 수많은 친구를 사귀고 무엇보다도 새로운 내용을 배

우고, 배우고, 또 배우면서 놀라운 경험을 하고 있다. iOS SDK는 계속해서 진화하고 있으며 매번

새로운 버전이 출시될 때마다 새롭게 익혀야 할 개념과 마스터해야 할 새로운 디자인 패턴을 내

놓고 있다.

그럼 개정판에서는 어떤 내용이 달라졌을까? 간단히 말해 수많은 내용이 달라졌다! 이 책을

처음 시작하는 독자를 위해 저자들은 책의 모든 코드를 한 줄씩 살펴보고 가장 최신 버전의 iOS

와 SDK에 맞게끔 각 프로젝트의 코드를 수정했다. 모든 프로젝트는 가장 최신 버전인 XCode 4

를 기준으로 생성했다. 또 책의 설명 또한 최신 버전에 맞게끔 모두 수정했다.

그럼 이 책의 과거 버전을 갖고 있는 독자가 개정판을 꼭 사야 할까? 좋은 질문이다. 물론 이 책

전반에는 작은 수정사항들도 수없이 반영됐지만 주요 수정사항 또한 있다. 개정판에서는 두 개

의 장을 추가했다. 이 중 한 장은 아이패드용 프로그래밍과 관련한 장이고 다른 장은 다중 스레

딩과 백그라운드 처리와 관련한 장이다. 두 장은 모두 새로운 코드를 보여주며 iOS 4를 염두에

두고 작성됐다.

간단히 말해 우리 저자들은 이 책의 내용을 훨씬 더 좋게 개정했다. 이 책의 이전 버전을 이미

살펴봤고 책의 내용 또한 모두 익숙하다면 이 책이 출판될 즈음 저자들이 집필하고 있을 'More

iPhone 4 Development'를 살펴보길 바란다.

이 책의 초판 또는 두 번째 개정판을 아직 다 읽지 못했거나 아직까지 개념이 정리되지 않는다

면, 또는 우리 저자들을 도와주고 싶은 마음이 든다면 세 번째 개정판인 이 책을 당연히 추천한

다. 우리 저자들은 독자들의 지원에 항상 감사를 드린다. 저자들에게 독자들이 만든 앱을 알려주

려면 http://iphonedevbook.com에 들러서 글을 남기면 된다. 이 포럼에서 여러 독자들을 만날

수 있기를 희망한다. 그럼 즐거운 코딩 시간이 되길!

- 데이브, 잭, 제프

Page 24: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

Beg

inni

ng iP

hone

4

Dev

elop

men

t

Page 25: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

1

01정글에 온 것을 환영한다

이 책을 구매한 독자들은 아이폰, 아이팟 터치, 아이패드 애플리케이션을 만들고 싶어서 책을 샀

을 것이다. iOS는 이들 기기의 핵심 소프트웨어로서, 앞으로도 한동안은 iOS만큼 새롭고 흥미로

운 플랫폼은 또 나오기 어려울 것이다. 실제로 오늘날 iOS는 가장 흥미로운 모바일 플랫폼이다.

특히나 애플은 iOS 애플리케이션을 개발하는 데 필요한 훌륭한 개발 도구들과 더불어 개발 문

서를 충실히 제공하고 있다. iOS SDK의 4 버전 출시와 더불어 이런 상황은 더 좋아졌다.

이 책에 대한 소개

이 책은 iOS 애플리케이션의 개발 여정을 시작할 수 있게 도와주는 가이드 서적이다. 이 책의 목

적은 독자들이 처음 배울 때 혼자서 이해하기 힘든 내용들을 쉽게 익힐 수 있게끔 도와줌으로

써 iOS 애플리케이션의 동작 원리를 이해할 수 있게 해주고 iOS 애플리케이션을 개발하는 방법

을 알려주는 것이다. 이 책에서는 iOS의 특정 기능에 맞춰 설계된 다양한 애플리케이션을 여러

개 개발하는 과정을 통해 이런 기능을 어떻게 활용하고 제어하는지 살펴본다. 끈기 있게 이 책의

내용을 모두 충실히 살펴본 후 책의 기초 지식을 모두 자기 것으로 소화하고, 독자들의 상상력과

애플에서 제공하는 방대한 문서의 지식까지 가미한다면 전문적인 아이폰 및 아이패드 애플리케

이션 개발에 필요한 지식을 모두 쌓을 수 있을 것이다.

데이브, 잭, 제프는 이 책의 포럼을 만들어 놓았다. 이 포럼에는 좋은 질문과 답이 올라오므로

수시로 들르도록 하자. 이 포럼의 위치는 http://iphonedevbook.com/forum이다.

Page 26: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

2 l 시작하세요! 아이폰 4 프로그래밍

책에 필요한 도구

iOS 애플리케이션 개발을 시작하려면 몇 가지 도구가 필요하다. 처음 개발을 시작하는 사람이라

면 스노우 레오파드(OS X 10.6.5 또는 이후 버전)를 구동하는 인텔 기반의 매킨토시 컴퓨터가

필요하다. 최근에 출시된 인텔 기반의 매킨토시 컴퓨터(랩톱이나 데스크톱)라면 문제 없이 사용

할 수 있다.

또 iOS 개발자 등록도 해야 한다. 애플에서는 iOS SDK를 내려 받기 전에 먼저 개발자 등록 과

정을 밟게 한다.

개발자로 등록하려면 http://developer.apple.com/ios/를 방문하면 된다. 그럼 오른쪽 그림 1-1

과 비슷한 페이지가 보인다.

먼저 [Log in] 버튼을 클릭한다. 그럼 애플 ID를 묻는 창이 나타날 것이다. 애플 ID가 없다면

[Register] [Get Started] [Create an Apple ID] 버튼을 클릭해서 새 아이디를 만든 후 로그인

한다. 로그인을 마치면 iOS 개발자 메인 페이지로 이동하게 된다. 이 페이지에서는 SDK 다운로

드 링크뿐 아니라 다양한 문서, 동영상, 예제 코드 등을 볼 수 있다. 이들 자료는 모두 애플에서

iOS 애플리케이션 개발 방법을 알려주기 위해 제공하는 자료들이다.

예제에 사용한 SDK 버전과 소스 코드

SDK와 Xcode가 발전함에 따라 이를 내려 받는 방법 또한 변한다. 때로는 SDK와 Xcode를

별도로 내려 받기도 하고, 때로는 한 번의 다운로드로 둘을 함께 내려 받기도 한다. 기본적으

로는 가장 최신의 (베타가 아닌) SDK와 Xcode를 내려 받는 게 제일 좋다.

이 책은 가장 최신 버전의 SDK와 호환되도록 작성했다. 어떤 곳에서는 기존 SDK와 호환되지

않을 수도 있는 버전 4 SDK의 새로운 함수나 메서드를 사용하기도 했다. 이런 부분은 이 책에

서 그때그때 언급하기로 하겠다.

책을 따라 할 때는 책의 웹사이트에서 가장 최신 버전의 소스 코드 압축 파일을 내려받는 게 좋다.

http://iphonedevbook.com

이 사이트에서 소스 코드를 내려 받으려면 먼저 포럼에 가입해야 한다. 이 책의 소스 코드는

위키북스 사이트(www.wikibook.co.kr)를 통해서도 내려 받을 수 있다.

저자들은 새로운 SDK 버전이 출시됨에 따라 소스 코드를 업데이트할 것이므로 책의 웹사이

트를 주기적으로 확인할 것을 권한다.

Page 27: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 3

이 페이지에서 내려 받아야 할 중요 프로그램 중 하나가 애플의 통합 개발 환경(IDE)인 Xcode

다. Xcode에는 소스 코드 작성 및 디버깅, 애플리케이션 컴파일, 애플리케이션 성능 튜닝에 필요한

도구가 모두 들어 있다. 이 책을 끝마치고 나면 독자들도 Xcode의 매력에 푹 빠지게 될 것이다.

그림 1-1 | 애플의 iOS 개발자 센터 웹사이트

Page 28: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

4 l 시작하세요! 아이폰 4 프로그래밍

개발 프로그램 옵션

무료 SDK 다운로드 옵션에는 맥에서 아이폰이나 아이패드 애플리케이션을 빌드하고 실행할 수

있는 시뮬레이터가 들어 있다. 이 시뮬레이터만 활용하더라도 iOS 프로그래밍을 배우는 데 충분

하다. 하지만 시뮬레이터에서는 아이폰의 가속도계나 카메라 같은 하드웨어 의존적인 기능들을

지원하지 않는다. 또 무료 옵션만으로는 애플리케이션을 실제 아이폰이나 다른 기기에 설치할

수 없을뿐더러 애플의 앱 스토어에서 애플리케이션을 배포할 수도 없다. 이런 기능들을 모두 사

용하려면 무료가 아닌 나머지 옵션 가운데 하나를 등록해야 한다.

▶ 표준 프로그램은 1년에 99달러가 든다. 표준 프로그램에서는 개발 도구와 자료, 기술 지

원, 애플 앱 스토어를 통한 애플리케이션 배포 등을 제공하고, 제일 중요한 iOS 기기상에

서의 테스트 및 디버깅 기능을 제공한다.

▶ 기업용 프로그램은 1년에 299달러가 든다. 이 프로그램은 인 하우스 iOS 애플리케이션을

개발하는 회사 또는 여러 개발자가 프로젝트에 참여해 애플 앱 스토어에서 애플리케이션

을 배포하고자 하는 기업용 프로그램이다.

이들 옵션에 대한 상세 설명은 http://developer.apple.com/programs/ios와 http://developer.

apple.com/programs/ios/enterprise에 잘 나와 있다.

iOS는 항상 다른 기업들의 무선 인프라를 활용해 모바일 기기의 지속적인 인터넷 연결 기능을

지원하므로, 애플에서는 맥 개발자에 대한 규제보다 iOS 개발자에 대한 규제를 훨씬 더 엄격히

적용한다(실제로 맥 개발자는, 적어도 이 책을 쓰고 있는 현 시점 기준으로, 애플의 감독이나 승

인 없이도 프로그램을 마음대로 개발하고 배포할 수 있다 1 ). 아이팟 터치와 와이파이 버전의 아

이패드의 경우 다른 기업의 인프라를 사용하지 않지만 이들 기기에 사용되는 애플리케이션 또한

똑같은 규제를 받는다.

애플에서 이런 규제를 강제하는 것은 개발자들을 괴롭히기 위한 것이 아니라 악의적인 프로

그램이나 품질이 떨어지는 프로그램이 무분별하게 배포됨으로써 공유 네트워크의 성능을 저해

하는 것을 최소화하기 위한 것이다. 이렇게 보면 iOS용 애플리케이션 개발 및 배포 과정에 넘어

야 할 난관이 많은 것처럼 보이지만 애플에서는 개발 과정의 고통을 가능한 한 줄이기 위해 모든

노력을 기울였다. 실제로 99달러라는 등록 비용도 예컨대 마이크로소프트의 IDE인 비주얼 스튜

디어의 구매 비용과 비교하면 매우 싼 편에 속한다.

1   (옮긴이) 맥 앱스토어의 경우 아이폰과 마찬가지로 애플의 자체 심사를 거쳐 애플리케이션을 앱 스토어에 등록해야 한다.

Page 29: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 5

당연한 말이지만 iOS 애플리케이션을 개발하려면 아이폰, 아이팟 터치, 또는 아이패드가 필요

하다. 물론 대부분의 코드는 iOS 시뮬레이터를 통해 테스트하지만 모든 프로그램을 시뮬레이터

로 테스트할 수 있는 건 아니다. 또 시뮬레이터로 테스트할 수 있는 코드라 하더라도 애플리케이

션을 일반에 공개할 생각이라면 먼저 실제 기기에서 엄격한 테스트를 거쳐야 한다.

노트

표준 또는 기업용 프로그램에 등록할 생각이라면 지금 당장 등록하자. 등록 승인에 다소 시간

이 걸리고, 등록이 승인된 후부터 비로소 실제 기기에서 애플리케이션을 실행할 수 있기 때문

이다. 하지만 이 책의 처음 몇 장에서 만들 프로젝트를 비롯해 책의 대다수 애플리케이션은

iOS 시뮬레이터에서도 잘 동작하므로 크게 걱정하지 않아도 된다.

책을 이해하는 데 필요한 배경 지식

이 책에서는 독자들이 어느 정도의 프로그래밍 지식은 갖추고 있다고 가정한다. 이 말은 독자들

이 객체 지향 프로그래밍(객체, 순환문, 변수 등의 의미는 이해할 것이라 믿는다)의 기본 지식을

이해할 것이라고 가정한다는 뜻이다. 또 독자들은 오브젝티브-C 언어에도 익숙하리라 가정한다.

이 책에서 계속 사용하게 될 SDK의 일부인 코코아 터치는 오브젝티브-C 2.0 언어를 사용한다.

이 책에서는 오브젝티브-C 2.0 언어를 사용할 때마다 주요 기능을 강조하고 동작 원리와 왜 이런

기능을 사용하는지 설명한다.

독자들은 사용자 측면에서 iOS 자체도 잘 이해해야 한다. 애플리케이션을 개발하는 다른 플

랫폼을 대할 때와 마찬가지로 아이폰, 아이패드, 아이팟 터치의 미묘한 차이와 사용성을 잘 이해

하기 바란다. 시간을 내서 iOS 인터페이스와 친해지고 애플의 아이폰 및/또는 아이패드 애플리

케이션의 외양과 느낌을 몸에 익히자.

Page 30: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

6 l 시작하세요! 아이폰 4 프로그래밍

오브젝티브-C 입문자라면?

오브젝티브-C로 프로그램을 만든 경험이 없다면 처음 시작하는 데 도움을 줄 수 있는 자료가

몇 가지 있다.

▶ Learn Objective-C on the Mac은 맥 프로그래밍 전문가인 마크 달림플과 스콧 내스

터(Apress, 2009)가 저술한 오브젝티브-C에 언어에 대한 훌륭한 저서다.

http://www.apress.com/book/view/9781430218159

▶ 애플의 언어 소개 사이트인 Learning Objective-C: A Primer를 참고한다.

http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/

Learning_Objective-C_A_Primer

▶ The Objective-C Programming Language는 오브젝티브-C에 대한 상세하고 방대

한 설명이 들어 있는 훌륭한 레퍼런스 가이드 서적이다.

http://developer.apple.com/library/ios/#documentation/Cocoa/

Conceptual/ObjectiveC

이 중 세 번째 책은 iBooks를 통해 아이폰, 아이팟 터치, 아이패드에서 무료로 내려 받을 수

도 있다. 이 책은 책의 내용을 따라 하면서 참조하기에 더 없이 좋은 책이다. 애플에서는 이

런 형태로 여러 권의 개발 서적을 출시했는데 앞으로도 이런 책들이 더 나오길 바란다. 애플

에서 출시한 개발 서적을 찾아보려면 iBooks에서 'apple developer publications'로 검색

하면 된다.

iOS 코딩의 차이점

코코아나 코코아의 전신인 NeXTSTEP, OpenStep을 사용해 본 적이 없다면 iOS 애플리케이션

개발에 사용하는 애플리케이션 프레임워크인 코코아 터치가 조금 낯설게 느껴질 것이다. 코코아

터치는 .NET이나 자바 애플리케이션 개발에 사용하는 일반 애플리케이션 프레임워크와는 근

본적인 차이점이 있다. 하지만 처음에 감이 안 오더라도 걱정하지 않아도 된다. 예제를 따라 하다

보면 자연스레 하나씩 이해가 될 것이다.

코코아나 NeXTSTEP을 사용해 프로그램을 개발해 본 경험이 있다면 iOS SDK의 내용 대부

분이 익숙할 것이다. 코코아 터치에서 대부분의 클래스는 맥 OS X 개발에 사용된 버전과 동일하

다. 또 코코아 터치에서 바뀐 클래스들조차 이전 버전에 사용된 클래스들의 기본 원칙을 그대로

준수하며 유사한 디자인 패턴을 사용한다. 하지만 코코아와 코코아 터치 사이에는 몇 가지 차이

점이 있다.

Page 31: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 7

독자들의 배경 지식과 상관없이 iOS 개발과 데스크톱 애플리케이션 개발 사이의 다음 차이점

몇 가지는 꼭 기억해야 한다.

단 하나뿐인 활성화된 애플리케이션

iOS에서는 모든 시점에 단 하나의 애플리케이션만 활성화되어 화면에 나타난다. iOS4부터는 사

용자가 홈 버튼을 누른 후에도 애플리케이션이 백그라운드에서 실행을 계속할 수 있지만, 이 또

한 특정 사용 용도와 상황에 국한된다.

애플리케이션이 활성화되어 있지 않거나 백그라운드에서 실행 중이면 애플리케이션은 CPU로

부터 아무런 관심도 받지 못하므로, 이 경우 열려 있는 네트워크 연결 등이 끊기게 된다. iOS4는

백그라운드 처리를 가능하게 함으로써 큰 발전을 이뤘지만 백그라운드에서 애플리케이션이 올

바르게 실행되게 하는 데는 개발자의 노력이 추가로 필요하다.

단 하나뿐인 창

데스크톱과 랩톱 운영체제에서는 여러 프로그램을 동시에 띄울 수 있고 여러 창을 제어할 수 있

다. 하지만 iOS에서는 애플리케이션에 주어지는 창이 단 하나뿐이다. 애플리케이션과 사용자와

의 상호작용은 모두 이 창 내에서 이뤄져야 하며, 이 창의 크기는 화면 크기로 제한된다. 2

제한된 접근

컴퓨터 프로그램은 프로그램을 실행한 사용자가 작업을 수행할 때 거의 모든 자원을 제한 없이

접근할 수 있다. 하지만 iOS에서는 애플리케이션이 접근할 수 있는 영역을 크게 제한한다.

iOS 프로그램에서는 애플리케이션과 관련해 생성된 iOS의 파일 시스템 영역을 통해서만 파일

을 읽고 쓸 수 있다. 이 영역은 애플리케이션의 샌드박스라고 부른다. 샌드박스는 애플리케이션

이 문서, 환경설정, 기타 저장할 데이터를 보관하는 공간이다.

애플리케이션의 접근은 다른 형태로도 제약을 받는다. 예를 들어 iOS에서는 낮은 번호의 네

트워크 포트에 접근하거나 데스크톱 컴퓨터에서 보통 루트나 관리자 접근이 필요한 기타 접근을

할 수 없다.

2   (옮긴이) 이를 유니태스킹(unitasking)이라고 부르기도 한다. uni는 라틴어 접두어로 하나(one)라는 뜻이며, 유니태스킹은 특

정 시점에 애플리케이션에서 단 하나의 작업만 함(또는 해야 함)을 나타내는 용어다. 애플에서는 맥 앱스토어를 통해 이런 유

니태스킹을 데스크톱으로까지 확장하려고 하고 있다.

Page 32: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

8 l 시작하세요! 아이폰 4 프로그래밍

제한된 응답 시간

iOS 애플리케이션의 사용 패턴으로 인해 iOS는 빠르게 반응해야 하는데, 이는 애플리케이션도

마찬가지다. 사용자가 프로그램을 실행하면 애플리케이션을 시작하고, 환경설정과 데이터를 로

드한 후 가능한 한 빨리 메인 뷰를 화면에 보여줘야 한다. 아무리 늦어도 2-3초 이내에 말이다.

프로그램이 실행 중인 경우에는 어느 때라도 실행이 중단될 수 있다. 사용자가 홈 버튼을 누르

면 iOS는 홈으로 이동하므로 애플리케이션은 빠르게 모든 내용을 저장하고 실행을 마쳐야 한다.

이때 정보를 저장하고 제어권을 넘겨주는 데까지 5초 이상 걸리면 시스템에서는 저장 여부와 상

관없이 애플리케이션의 프로세스를 그냥 죽인다.

iOS4에서는 애플리케이션이 시스템으로 제어를 넘겨줄 때 추가 시간을 요구할 수 있는 새로운

API가 추가되면서 이 상황이 다소 개선됐다.

제한된 화면 크기

아이폰의 화면은 실제로 근사하다. 아이폰이 처음 나왔을 때 아이폰은 당시 휴대용 기기로서는

최고 해상도의 화면을 보여줬다.

하지만 아이폰 디스플레이는 그다지 크지 않으므로 현대 컴퓨터 화면과 비교해 사용할 수 있

는 화면 공간이 많이 부족하다. 가장 최근에 나온 레티나 디스플레이 기기(아이폰 4 및 아이팟

터치 4세대)의 화면 해상도는 640×960이며 기존 기기의 해상도는 320×480 픽셀이다. 그런데

640×960 해상도의 레티나 디스플레이도 기존 크기의 아이폰에 촘촘히 화소를 배치한 것이므

로 해상도가 높다고 해서 더 많은 컨트롤을 배치할 수 있는 것은 아니다. 단지 기존보다 더 높은

해상도로 화면이 보일 뿐이다.

아이패드는 1024×768 디스플레이를 제공함으로써 이런 화면 제약을 조금 개선했지만 오늘날

기준으로 이 해상도가 큰 편은 아니다. 이를 다른 화면 크기와 비교해 보면, 이 책을 쓰고 있는 현

시점 기준으로 애플에서 가장 최근에 출시한 iMac은 1920×1080 픽셀을 지원하며, 가장 최근에

출시된 맥북은 1280×800 픽셀을 지원한다. 또 현재 기준으로 애플의 가장 큰 모니터인 27인치

LED 시네마 디스플레이는 무려 2560×1440 픽셀이라는 놀라운 해상도를 제공한다.

제한된 시스템 자원

과거 시절에 프로그래밍을 했던 개발자라면 256MB의 램과 8GB의 저장 공간을 가진 기기가 리

소스 제약이 있다는 말이 우습게 들릴 것이다. 물론 iOS 애플리케이션 개발은 48KB의 메모리를

Page 33: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 9

가진 기기에서 실행할 복잡한 스프레드시트 애플리케이션을 개발하는 것에 비할 바는 아니다.

하지만 iOS 애플리케이션의 화려한 그래픽 성격과 애플리케이션에서 처리하는 다양한 작업으로

인해 메모리는 매우 쉽게 소모된다.

현재 시판되는 iOS 기기들은 256MB 또는 512MB의 물리 RAM을 갖고 있다. 물론 이런 메모

리는 시간이 흐르면서 점차 늘어날 것으로 보인다. 이런 메모리 중 일부는 화면 버퍼 및 기타 시

스템 프로세스에 사용된다. 보통 애플리케이션에서 사용할 수 있는 최대 메모리는 전체 메모리

의 절반을 넘지 못하며, 실제 사용할 수 있는 메모리의 양은 이보다 훨씬 적을 수도 있다.

이렇게 얘기하면 iOS 기기 같은 작은 컴퓨터에서 꽤 많은 메모리를 사용한다는 생각이 들 수

있지만 iOS의 메모리와 관련해서는 한 가지를 더 고려해야 한다. 맥 OS X 같은 현대 컴퓨터 운영

체제는 사용하지 않는 대용량의 메모리를 스왑 파일이라는 디스크에 쓴다. 스왑 파일은 컴퓨터

에서 실제 사용할 수 있는 메모리보다 더 많은 메모리를 프로그램이 요청하더라도 프로그램을

계속 실행할 수 있게 해준다. 하지만 iOS에서는 애플리케이션 데이터 같은 휘발성 메모리를 스왑

파일에 쓰지 않는다. 이로 인해 애플리케이션에서 사용할 수 있는 메모리의 양이 iOS 기기에서

사용하지 않는 물리적인 메모리 크기로 제한될 수밖에 없다.

코코아 터치에는 메모리가 내려가고 있음을 애플리케이션에게 알려주는 내장 메커니즘이 있

다. 메모리가 부족하면 애플리케이션에서 불필요한 메모리를 제거해야 한다. 그렇지 못할 경우

애플리케이션이 강제 종료된다.

가비지 컬렉션의 부재

앞에서 코코아 터치가 오브젝티브-C 2.0을 사용한다고 설명한 바 있다. 하지만 iOS는 오브젝티

브-C 언어의 핵심 신기능 중 하나를 지원하지 않는다. 코코아 터치는 가비지 컬렉션을 지원하지

않는 것이다.

코코아 터치의 고유 기능

앞에서 코코아 터치가 코코아의 기존 기능 중 일부를 지원하지 않는다고 언급했으므로 현재 코

코아에 들어 있지 않거나 모든 맥에서 사용할 수 없는 iOS SDK만의 기능도 언급하는 게 공평할

것 같다.

▶ iOS SDK는 코어 로케이션(Core Location)을 통해 애플리케이션에서 iOS 기기의 현재 지

리 좌표를 알 수 있는 기능을 제공한다.

Page 34: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

10 l 시작하세요! 아이폰 4 프로그래밍

▶ 대다수 iOS 기기는 내장 카메라와 사진 라이브러리를 갖고 있으며 SDK를 통해 애플리케

이션이 이에 접근할 수 있는 기능을 제공한다.

▶ iOS 기기는 기기의 현재 움직임을 감지할 수 있는 가속도계(최신 아이폰 및 아이팟 터치

에서는 자이로스코프까지)를 갖고 있다.

다른 접근 방식

iOS 기기에 없는 두 가지를 들자면 물리적인 키보드와 마우스가 있다. 이 말은 일반 컴퓨터 응용

프로그램을 만들 때와는 전혀 다른 방식으로 사용자와 상호작용해야 함을 뜻한다. 다행히 이런

상호작용 중 대부분은 개발자를 위해 iOS에서 대신 처리해준다. 예를 들어 텍스트 필드가 들어

있는 애플리케이션에서 사용자가 텍스트 필드를 클릭하면 추가 코드 없이도 iOS에서 자동으로

키보드를 보여준다.

노트

현재 iOS 기기들은 블루투스를 통해 외부 키보드를 연결할 수 있는 기능을 제공한다. 이를 활

용하면 화면 공간을 절약하고 훌륭한 키보드 사용 경험을 전달할 수 있지만, 실제로 이렇게 사

용하는 사례는 드물다. 블루투스를 통한 마우스 연결 기능은 아직 옵션으로 제공되지도 않고

있다.

이 책에서 다루는 내용

다음은 이 책의 나머지 장에서 다룰 내용을 간략히 정리한 것이다.

2장에서는 Xcode의 단짝인 인터페이스 빌더를 활용해 간단한 인터페이스를 만들고 화면에

텍스트를 배치한다.

3장에서는 사용자가 누르는 버튼에 따라 런타임 시에 텍스트의 내용을 동적으로 업데이트하

는 애플리케이션을 개발함으로써 사용자 상호작용 프로그램의 개발을 시작한다.

4장에서는 iOS의 표준 UI 컨트롤을 몇 가지 더 살펴보면서 3장의 예제에 살을 덧붙인다. 또 경

고창과 액션 시트를 활용해 사용자가 결정을 내리게 하고, 사용자에게 어떤 일이 일어났음을

알려주는 법을 살펴본다.

Page 35: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 11

5장에서는 iOS 애플리케이션을 가로와 세로 모드에서 사용할 수 있게 해주는 메커니즘인 자

동 회전과 자동 크기 조절 속성을 살펴본다.

6장에서는 고급 UI 컨트롤을 살펴보고 여러 뷰를 지원하는 애플리케이션의 작성법을 배운다.

이 장에서는 런타임 시에 사용자에게 보여줄 뷰를 변경하는 법을 배움으로써 애플리케이션의

활용 범위를 한층 더 넓힌다.

탭 바와 피커는 표준 iOS UI에 속한다. 7장에서는 이런 UI 요소를 구현하는 법을 살펴본다.

8장에서는 사용자에게 데이터 목록을 전달하는 주된 방법인 테이블 뷰를 살펴보고 계층적 내

비게이션 기반 애플리케이션의 기본 지식을 배운다. 또 애플리케이션 데이터를 사용자가 검색

할 수 있게 하는 기능을 살펴본다.

iOS 애플리케이션 인터페이스에서 가장 자주 등장하는 인터페이스 중 하나는 내부 뷰로 이동

해 더 많은 데이터와 상세 정보를 확인할 수 있는 계층적 리스트 인터페이스다. 9장에서는 이

런 표준 인터페이스를 구현하는 법을 살펴본다.

다른 iOS 기기와는 기기 크기에서 차이가 있는 아이패드는 GUI를 보여줄 때 다른 접근 방식

을 사용해야 하며, SDK에서는 이를 도와주는 일부 컴포넌트를 제공한다. 10장에서는 아이패

드와 관련한 SDK를 활용하는 법을 살펴본다.

11장에서는 애플리케이션 환경설정을 구현하는 법을 살펴본다. 애플리케이션 환경 설정을 활

용하면 사용자들이 애플리케이션 단위로 자신이 선호하는 환경을 설정할 수 있다.

12장에서는 iOS에서의 데이터 관리법을 알아본다. 이 장에서는 애플리케이션 데이터를 보관

할 객체를 생성하는 법을 설명하고 이런 데이터를 iOS의 파일 시스템에 영속화하는 법을 살펴

본다. 또 코어 데이터(Core Data)를 활용하는 기본 방법을 다룸으로써 데이터를 쉽게 저장하

고 조회하는 법을 설명한다.

iOS4부터는 개발자들이 그랜드 센트럴 디스패치(Grand Central Dispatch)를 통해 다중 스레

드를 활용한 애플리케이션을 개발하고 특정 환경에서 애플리케이션이 백그라운드에서 실행되

게 할 수 있다. 13장에서는 이를 구현하는 법을 살펴본다.

그림 그리는 것을 싫어하는 사람은 없을 것이다. 14장에서는 커스텀 드로잉을 살펴본다. 이 장

에서는 쿼츠 2D와 오픈GL ES를 활용한 기본 드로잉을 설명한다.

모든 iOS 기기에 공통으로 들어 있는 멀티 터치 화면은 사용자로부터 다양한 제스처를 입력

받을 수 있다. 15장에서는 핀치, 스와이프 같은 기본 제스처를 인식하는 법을 배운다. 또 새로

Page 36: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

12 l 시작하세요! 아이폰 4 프로그래밍

운 제스처를 정의하는 방법을 살펴보고 언제 새로운 제스처를 사용하는 게 적절한지도 설명

한다.

iOS는 코어 로케이션을 활용해 위도와 경도를 판단할 수 있다. 16장에서는 코어 로케이션을

활용해 현재 iOS 기기가 있는 위치를 판단하는 법을 살펴보고 이 정보를 활용해 세계 정복에

나선다.

17장에서는 iOS의 가속도계 및 자이로스코프와 연동하는 법을 살펴보고, 이를 통해 현재 기

기가 움직이는 방향과 속도를 판단한다. 또 이런 정보를 활용해 애플리케이션에서 구현할 수

있는 재미있는 예제를 살펴본다.

거의 모든 iOS 기기에는 카메라와 사진 라이브러리가 있으며 올바른 방식으로 요청하기만 하

면 애플리케이션에서는 이 둘을 모두 활용할 수 있다. 18장에서는 이런 요청 방법을 살펴본다.

iOS 기기는 현재 90개국 이상에서 사용한다. 19장에서는 애플리케이션의 전 영역을 다른 언어

로 쉽게 번역할 수 있도록 애플리케이션을 개발하는 법을 배운다. 이를 잘 활용하면 애플리케

이션의 사용층을 훨씬 넓힐 수 있을 것이다.

이 책을 끝마치고 나면 아이폰 및 아이패드 애플리케이션 개발에 필요한 구성 요소를 모두 마

스터할 수 있다. 그럼 책을 다 읽고 난 후에는 어떤 자료를 봐야 할까? 20장에서는 iOS SDK를

마스터하기 위한 여정의 다음 목적지를 어디로 정하는 게 좋을지 살펴본다.

개정판에서 달라진 점

이 책의 초판이 출시된 후 iOS 개발 커뮤니티는 눈에 띄게 성장했다. 그 사이 SDK는 지속적으로

발전했으며 애플에서는 계속해서 SDK의 업데이트 버전을 내놓고 있다.

물론 그동안 저자들도 바빴다. iOS SDK 4가 출시된다는 소식을 듣자마자 우리는 바로 새 책의

집필 작업에 착수했으며, 책에 들어 있는 예제 프로젝트를 하나씩 수정해 각각의 프로젝트가 최

신 버전의 Xcode와 SDK에서 컴파일됨은 물론, 코코아 터치에서 제공하는 가장 최신 기능과 최

고의 기능들을 모두 활용할 수 있게 했다. 이 책에서는 전반적으로 수많은 작은 수정 사항들이

반영됐으며, 코드와 설명 모두 내용이 크게 바뀐 부분 또한 상당히 많다. 개정판에서는 스레딩과

멀티 스레딩에 대한 장을 추가하고 아이패드 프로그래밍에 대한 장도 추가했다. 또한 책에 사용

된 캡처 화면도 모두 새로 첨부했다.

Page 37: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

01 정글에 온 것을 환영한다 l 13

시작할 준비가 되었나?

iOS는 놀라운 컴퓨팅 플랫폼이며 개발의 즐거움을 만끽할 수 있는 흥미롭고 새로운 분야다. iOS

프로그래밍은 다른 플랫폼에서 개발하는 것과는 전혀 다른 새로운 경험이 될 것이다. 익숙하게

느껴지는 내용도 많겠지만 조금 낯선 부분도 보일 것이다. 하지만 책의 코드를 따라 하다 보면 이

런 개념들이 하나씩 정리되면서 점차 개념이 잡힐 것이다.

이 책의 예제를 다 따라 한다고 해서 iOS 고급 개발자 인증서 같은 것이 바로 주어지거나 하지

않는다는 사실을 기억하자. 책을 볼 때는 다음 장으로 넘어가기 전에 이 장에서 한 작업 내용과

왜 이런 작업을 했는지 이해한 후 넘어가자. 또 코드를 수정하는 것을 겁내지 말자. 코코아 터치

같은 환경에서 복잡한 코딩 내용을 정리할 때는 코드를 이리저리 수정하고 결과를 확인하는 게

가장 많은 도움이 되기 때문이다.

서론은 이쯤으로 하고, iOS SDK가 설치돼 있다면 바로 다음 페이지로 넘어가자. 아직 iOS

SDK를 설치하지 않았다면 지금 바로 설치하자. 준비가 됐다면 이제 여정을 시작해 보자!

Page 38: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

Beg

inni

ng iP

hone

4

Dev

elop

men

t

Page 39: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

15

02티키 신 달래기

독자들도 이미 잘 알고 있겠지만 프로그래밍 기술 서적에서 첫 번째 프로젝트를 'Hello, World!'

프로젝트로 만드는 건 하나의 전통이 됐다. 이 책에서는 이런 전통을 한번 깨보는 것을 고민했지

만, 그런 관례를 깨는 것에 티키 신이 크게 노해서 우리에게 재앙을 내릴까봐 두려운 마음이 들었

다. 그래서 이 책에서도 'Hello, World!' 프로젝트부터 설명을 시작하기로 했다.

이 장에서는 Xcode와 인터페이스 빌더를 사용해 'Hello, World!'라는 간단한 텍스트를 iOS 기

기 시뮬레이터에 보여주는 iOS 애플리케이션을 만든다. 이 장에서는 Xcode의 iOS 애플리케이

션 프로젝트를 생성할 때 포함되는 내용을 살펴보고 인터페이스 빌더를 활용해 애플리케이션의

UI를 디자인하는 세부 사항을 직접 체험한다. 이 작업까지 마치고 나면 실제 iOS 애플리케이션

처럼 애플리케이션을 만들기 위해 애플리케이션에 아이콘과 고유 식별자를 부여할 것이다.

이 장에서 할 일이 많으므로 바로 작업을 시작하자.

Xcode에서의 프로젝트 설정

지금쯤이면 독자들의 컴퓨터에도 Xcode와 iOS SDK가 모두 설치돼 있을 것이다. 책의 내용을

따라 하려면 이 책의 웹사이트에서 제공하는 책의 예제 프로젝트 압축 파일도 내려 받아야 한다.

책의 예제 소스 링크는 다음과 같다.

http://www.iphonedevbook.com/forum/

이 책의 포럼에서는 최신의 예제 코드를 내려 받을 수도 있고, 질문에 대한 답을 들을 수도 있

으며, 비슷한 생각을 가진 다른 사람들을 만날 수도 있다. 물론 책의 예제 코드는 Apress의 웹사

이트와 위키북스 홈페이지에서도 받을 수 있다.

Page 40: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

16 l 시작하세요! 아이폰 4 프로그래밍

http://www.apress.com

http://www.wikibook.co.kr

노트

물론 책의 예제 프로젝트 압축 파일에는 책에 소개된 프로젝트의 전체 코드가 모두 들어 있지

만, 이 책의 내용을 십분 활용하려면 내려 받은 예제 코드를 그냥 실행하는 것보다는 책의 코

드를 직접 입력해 볼 것을 권장한다. 책의 코드를 직접 입력하다 보면 프로젝트를 진행함에 따

라 점점 더 다양한 개발툴을 익힐 수 있기 때문이다. 한 프로그램 언어를 알고 있다가 다른 프

로그램 언어를 새로 배울 때 인터페이스 요소를 직접 클릭하고 드래그하거나, 소스를 스크롤

해 가면서 직접 수정하는 것보다 더 효과적으로 언어를 익히는 방법은 없다.

이 책의 첫 번째 프로젝트는 02 - Hello World 폴더에 들어 있다. 직접 프로젝트를 생성할 경우

에는 책에서 생성할 프로젝트들을 모두 보관할 새 폴더를 생성한다. 책의 내용을 따라 하면서 새

로 생성하는 프로젝트는 모두 이 마스터 폴더에 저장한다.

이제 Xcode를 실행한다. Xcode는 /Developer/Applications 위치에 들어 있다. 좀 더 쉽게 풀

어서 설명하면 하드 드라이브의 최상단에는 Developer라는 폴더가 있을 것이다. 이 폴더 안에

Applications라는 폴더가 있는데, 바로 이 폴더 안에 Xcode.app이라는 애플리케이션이 들어 있

다. Xcode를 실행하기 전에는 독(dock)에 아이콘을 드래그해 두는 게 좋다. Xcode가 들어 있는

폴더에서는 Interface Builder.app 1 이라는 프로그램도 볼 수 있다. 이 아이콘도 독에 드래그한다.

이들 두 프로그램은 책에서 앞으로 계속 사용하게 될 것이다.

Xcode를 실행한 게 이번이 처음이더라도 걱정하지 않아도 된다. 이 장에서는 잠시 후 새 프로

젝트를 생성하는 과정을 차례로 안내해줄 것이다. 이미 Xcode에 익숙한 독자라면 이 부분은 그

냥 건너뛰어도 상관없다.

Xcode를 처음 실행하면 그림 2-1과 같은 환영창이 나타난다. 이 창에서는 새 프로젝트를 생성

할 수도 있고 Getting started with Xcode 튜토리얼을 참조할 수도 있고, 애플 개발자 커넥션 웹

사이트로 이동할 수도 있다. 이 창의 오른쪽에 있는 리스트에서는 최근에 생성한 프로젝트를 선

택해 바로 이동할 수 있다. 이 프로젝트가 첫 번째 프로젝트라면 이 리스트가 비어 있을 것이다.

1   (옮긴이) 인터페이스 빌더는 Xcode 4.x에서는 Xcode 프로그램으로 통합됐다. 이 책의 원서는 Xcode 3.x 기반으로 작성됐지만

역서에서는 새로 아이폰 프로그래밍을 시작할 개발자가 Xcode 4.x를 대부분 설치할 것을 감안해 Xcode 4.x를 기반으로 설명

하겠다. 따라서 이 부분은 기존 Xcode 3.x를 사용하는 개발자에게만 해당한다.

Page 41: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 17

잠시 시간을 내서 애플 개발자 커넥션 웹사이트로 이동해서 iOS 개발자 프로그램을 살펴보자.

애플리케이션을 개발해 앱스토어에서 판매할 생각이라면 이 프로그램에 꼭 등록해야 한다. 등

록이 승인되기까지는 다소 시일이 걸리므로, 지금 바로 짬을 내서 등록하면 도움이 될 것이다.

아마도 여러분이 이 책을 다 읽기 전에는 애플 개발자 프로그램의 승인이 돼 있을 것이다.

매번 Xcode가 실행될 때마다 환영창이 나타나는 게 싫다면 환영창을 닫기 전에 Show this

window when Xcode launches 체크박스를 선택 해제하면 된다. 환영창에 나와 있는 정보들이

궁금하다면 얼마든지 이 창의 정보를 천천히 읽어봐도 상관없다. 창의 내용을 다 읽었다면 창을

닫고, 다음 단계로 넘어간다.

그림 2-1 | Xcode의 환영창. Xcode를 처음 실행했다면 최근 프로젝트에 아무것도 나와 있지 않을 것이다.

하지만 이 책의 내용을 따라 하다 보면 이곳에 프로젝트가 하나씩 쌓일 것이다.

Page 42: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

18 l 시작하세요! 아이폰 4 프로그래밍

노트

컴퓨터와 연결된 iOS 기기가 있다면 Xcode를 처음 실행할 때 연결된 기기를 개발에 사용할지

묻는 대화상자가 보일 것이다. 또는 이때 현재 애플리케이션과 연계된 기기들의 목록을 보여

주는 Organizer 창이 나타날 수도 있다. 지금은 일단 Ignore 버튼을 클릭하거나 Organizer

창이 나타날 경우 창을 닫아 버린다. 유료 iOS 개발자 프로그램에 등록했다면 iOS 기기를 개

발 및 테스트에 활용하는 방법을 알려주는 프로그램 포탈에 바로 접근할 수 있다.

File New New Project...를 선택하거나 zN 단축키를 사용해 새 프로젝트를 생성한다.

이렇게 하면 새 프로젝트 대화상자(그림 2-2)가 표시된다. 이 창의 왼쪽은 iOS와 Mac OS X의 두

영역으로 나뉘어 있다.

그림 2-2 | 새 프로젝트 대화상자. 새 프로젝트 대화상자에서는 다양한 파일 템플릿을 선택해 새 프로젝트

를 생성할 수 있다.

그림 2-2에 보이는 것처럼 iOS 헤더 아래에 있는 Application을 선택하고 나면 우측 상단 화면

에 다양한 아이콘을 볼 수 있을 것이다. 이들 아이콘은 iOS 애플리케이션 개발의 시작점으로 활

용할 수 있는 별도 프로젝트 템플릿을 나타낸다. View-based Application이라는 아이콘은 이

중 가장 간단한 템플릿으로서, 이 책의 처음 몇 장에서는 이 프로젝트만 사용한다. 나머지 아이

Page 43: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 19

콘들은 공통 iOS 애플리케이션 인터페이스를 생성하는 데 필요한 추가 코드 및/또는 자원을 제

공한다. 이 내용은 이후 장들에서 살펴본다.

(그림 2-2와 같이) View-based Application 아이콘을 클릭하고 Product Name으로 Hello

World를, Company Identi�er로 yourcompany를 입력한 후, 창의 가운데 있는 Device Family

팝업 메뉴에서 iPhone을 선택한다. 이렇게 하면 Xcode에서는 아이폰 및 아이폰의 특정 화면 크

기에 맞춰 애플리케이션을 개발하려는 것을 알게 된다. 이 책을 쓰고 있는 현 시점 기준으로 이

템플릿에서 지원하는 iOS 기기는 아이폰과 아이패드뿐이다. 지금은 일단 아이폰 프로그램만 개

발한다. 아이패드는 이 책에서 나중에 다루므로 걱정하지 않아도 된다.

프로젝트 생성을 진행하기 위해 Next 버튼을 클릭한다. 그럼 새 프로젝트를 저장할 수 있는

(그림 2-3과 같은) 표준 저장 대화상자가 나타난다. 이때는 원하는 위치에 프로젝트를 저장하면

된다. 물론 도큐먼트 폴더에 저장해도 괜찮지만 Xcode 프로젝트에 사용할 전용 폴더를 따로 둘

것을 권장한다.

그림 2-3 | 프로젝트명과 프로젝트의 위치 선택 화면

Xcode 프로젝트 창

Create를 누르면 Xcode에서는 프로젝트를 생성하고 열어줄 것이다. 그럼 그림 2-4와 같은 새 프

로젝트 창이 나타난다. 프로젝트 창에는 수많은 정보가 들어 있으며 iOS 개발을 할 때 대부분의

시간을 보내는 곳도 다름 아닌 프로젝트 창이다.

Page 44: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

20 l 시작하세요! 아이폰 4 프로그래밍

그림 2-4 | Xcode의 Hello World 프로젝트

프로젝트 창에서는 자주 사용하는 명령을 바로 접근할 수 있게끔 툴 바를 보여준다. 툴 바 아

래에는 창이 메인 영역과 편집 영역으로 나뉘어 있다.

프로젝트의 창의 왼쪽은 Groups & Files 영역(이후 ‘그룹 & 파일’ 영역)이라고 부른다. 프로젝

트를 구성하는 리소스는 다양한 프로젝트 관련 설정과 더불어 모두 이곳에서 그룹으로 관리된

다. Finder에서와 마찬가지로 이곳에서도 항목의 왼쪽 삼각형을 클릭하면 항목을 펼쳐서 하위

항목을 볼 수 있다. 삼각형을 다시 한 번 클릭하면 하위 항목을 숨길 수 있다.

프로젝트 창의 우측 영역은 Editor 영역(이후 편집 영역)이라고 부른다. 그룹 & 파일 영역에서

단일 파일을 선택하면 Xcode에서는 자동으로 파일 종류에 따라 보여줄 방법을 결정해 편집 영

역에 파일 내용을 보여준다. 소스 코드처럼 편집할 수 있는 파일들은 이곳에서 바로 편집할 수도

있다. 실제로 애플리케이션의 소스 코드를 작성하고 수정하는 곳이 바로 이 편집 영역이다. 아울

러 Xcode 4.x부터는 인터페이스 빌더가 내장돼 이곳에서 뷰를 바로 편집할 수도 있게 됐다.

이제 다양한 용어를 들어서 화면 구성을 설명했으니 이어서 그룹 & 파일 영역부터 살펴보자.

그룹 & 파일 영역의 목록에서 첫 번째 항목은 프로젝트명과 같은 이름을 갖고 있어야 한다. 이

책의 경우 이 항목의 이름은 Hello World다. 이 항목에는 프로젝트와 관련한 소스 코드와 기타

자원을 추가할 수 있다. 당분간은 Hello World 하위에 있는 항목들 이외에 그룹 & 파일 영역의

나머지 항목은 신경쓰지 않아도 된다.

Page 45: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 21

그림 2-4를 살펴보자. 이 그림에서는 Hello World의 왼쪽에 있는 삼각형 아이콘이 펼쳐져 있

고 하위에 네 개의 폴더가 들어 있음을 볼 수 있다. 이들 폴더는 각각 Hello World, Supporting

Files, Frameworks, Products 폴더다. 이어서 간단히 각 폴더의 사용 용도를 살펴보자.

▶ Hello World 폴더는 프로젝트명과 동일한 이름의 폴더로 애플리케이션을 개발할 때 대

부분의 시간을 보내는 폴더다. 이 폴더에는 전체 오브젝티브-C 클래스들이 모두 들어가

므로 작성하는 코드는 대부분 이곳에 보관한다. 코드 구조를 조직화하려면 Hello World

폴더에 하위 폴더를 만들어도 상관없다. 다음 장에서는 이런 폴더를 사용할 것이다. 이 폴

더에는 다음 파일들도 들어 있다.

² Hello_WorldViewController.xib: 이 파일에는 인터페이스 빌더 프로그램에서 사용

하는 정보가 들어 있다. 인터페이스 빌더는 이 장에서 잠시 후 살펴볼 것이다.

² MainWindow.xib: 이 파일은 애플리케이션의 메인 인터페이스 빌더(또는 'nib') 파

일이다. 이 장에서 개발하는 간단한 애플리케이션의 경우 이 파일은 건드리지 않아도

된다. 이 파일은 이후 장들에서는 좀 더 복잡한 인터페이스를 다루면서 자세히 살펴

본다.

▶ Supporting Files 폴더에는 오브젝티브-C 클래스가 아닌 소스 코드들이 들어간다. 새로

운 아이폰 애플리케이션 프로젝트를 생성하면 이 폴더에는 네 개의 파일이 들어간다. 애

플리케이션은 자체 샌드박스에서 실행되므로 애플리케이션 아이콘 이미지와 기타 이미

지, 사운드 파일, 동영상 파일, 텍스트 파일 등 필요로 하는 파일들이 있다면 이 폴더에 모

두 포함시켜야 한다. iOS 애플리케이션에서는 아이폰의 사진이나 주소록에 접근하는 것

같은 승인된 API를 제외하고는 기기상의 다른 위치에 있는 파일에 접근할 수 없기 때문이

다. 이 폴더에는 다음 네 항목이 들어 있을 것이다.

² Hello_World_Pre�x.pch: 확장자 .pch는 ‘사전 컴파일된 헤더(precompiled header)’

의 약어다. 이 파일은 이 프로젝트에서 사용되는 외부 프레임워크의 헤더 파일 목록

을 말한다. Xcode에서는 이 파일에 들어 있는 헤더들을 미리 컴파일함으로써 Build

를 선택할 때 프로젝트를 컴파일하는 시간을 줄인다. 주로 사용하는 헤더 파일은 기

본으로 포함돼 있으므로 이런 헤더 파일에 대한 부분은 한동안은 걱정하지 않아도

된다.

² main.m: 이 파일은 애플리케이션의 main() 함수가 있는 파일이다. 보통 이 파일은 직

접 편집하거나 수정하지 않아도 된다.

Page 46: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

22 l 시작하세요! 아이폰 4 프로그래밍

² Hello_World-Info.plist: 이 파일은 애플리케이션에 대한 정보를 담고 있는 프로퍼티

리스트 파일이다. 이 파일은 이 장에서 잠시 후 살펴본다.

² InfoPlist.strings: plist 파일의 지역화 파일이다.

▶ Frameworks 폴더는 이미지나 사운드 파일 같은 리소스뿐 아니라 코드도 포함하는 특

수 라이브러리다. 이 폴더에 추가하는 프레임워크나 라이브러리는 모두 애플리케이션과

연결되며, 코드에서는 이런 프레임워크나 라이브러리에 포함된 객체, 함수, 자원에 접근

해 이를 활용할 수 있다. 주로 사용하는 프레임워크와 라이브러리는 프로젝트에 기본으

로 연결되므로 대부분의 경우 이 폴더에 아무것도 추가하지 않아도 된다. 하지만 간혹 사

용하는 라이브러리나 프레임워크는 기본으로 포함되지 않는데, 이런 프레임워크를 연결

하는 방법은 이 책에서 나중에 애플리케이션을 개발하면서 같이 살펴보겠다.

▶ Products 폴더에는 프로젝트가 컴파일을 통해 생성한 애플리케이션이 들어 있다.

Products 폴더를 펼쳐보면 Hello World.app이라는 항목이 보일 것이다. 이 애플리케이

션이 바로 이 프로젝트에서 생성하는 애플리케이션이다. Hello World.app은 이 프로젝

트의 유일한 애플리케이션이다. 아직까지는 프로젝트를 컴파일하지 않았으므로 Hello

World.app이 파일을 찾을 수 없다는 뜻으로 빨갛게 표시돼 있을 것이다. 파일명을 빨갛

게 강조하는 방식은 Xcode에서 내부의 물리적인 파일을 찾을 수 없다는 뜻으로 사용하

는 경고 표시다.

노트

그룹 & 파일 영역의 '폴더들'은 맥의 파일 시스템상의 폴더와 꼭 일치하지 않을 수도 있다. 이

들 폴더는 Xcode에서 전체 자원을 조직화하고 애플리케이션을 개발할 때 찾고 있는 정보를

빠르게 찾을 수 있게 도와주는 논리적인 그룹이다. 하드 드라이브에서 프로젝트의 폴더를 들

여다보면 Hello World라는 폴더는 있는 반면 Supporting Files 같은 폴더는 볼 수 없을 것

이다. 이런 폴더에 속한 항목들은 주로 프로젝트의 루트 디렉터리에 저장되지만, 원한다면 다

른 위치로 옮기거나 프로젝트 폴더 바깥으로 빼도 상관없다. Xcode의 프로젝트 계층 구조는

파일 시스템의 계층 구조와는 전혀 무관하다. 예를 들어 Xcode의 Hello World 폴더에서 파

일을 밖으로 빼낸다고 해서 하드 드라이브에 있는 파일의 위치가 바뀌지는 않는다.

Page 47: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 23

인터페이스 빌더의 소개

이제 Xcode에 대한 기본 내용은 어느 정도 익혔으므로 아이폰 소프트웨어를 개발할 때 사용하

는 다이나믹 듀오의 또 다른 멤버를 살펴보자. 바로 인터페이스 빌더인데, 보통 줄여서 IB라고 많

이 부른다.

프로젝트 창의 그룹 & 파일 영역 목록에서 Hello World 그룹을 펼친 후 Hello_WorldView

Controller.xib 파일을 클릭해 보자. 그럼 인터페이스 빌더가 보일 것이다. 이번이 처음으로 인터

페이스 빌더를 사용하는 것이라면 그림 2-5에 보이는 것과 비슷한 형태의 창이 나타날 것이다. 과

거에 인터페이스 빌더를 사용해봤다면 가장 최근에 인터페이스 빌더를 사용한 모습 그대로 인터

페이스 빌더가 나타날 것이다.

그림 2-5 | 인터페이스 빌더의 Hello_WorldViewController.xib

Page 48: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

24 l 시작하세요! 아이폰 4 프로그래밍

노트

인터페이스 빌더는 역사가 꽤 길다. 인터페이스 빌더는 1988년부터 NeXtSTEP, OpenSTEP,

맥 OS X 개발에 사용되다가 지금은 아이폰 개발에 사용된다. 인터페이스 빌더는 두 개의 파일

타입을 지원한다. .nib 확장자를 사용하는 기존 파일 형식과 .xib 확장자를 사용하는 새로운

파일 형식을 모두 지원하는 것이다. 아이폰 프로젝트 템플릿은 모두 기본적으로 .xib 파일 확

장자를 사용하지만 아주 최근까지만 하더라도 인터페이스 빌더의 파일들은 모두 .nib 파일 확

장자를 갖고 있었으므로, 대다수 개발자들은 인터페이스 빌더의 파일을 부를 때 nib 파일이라

고 많이 부른다. 인터페이스 빌더 파일들은 파일의 실제 확장자가 .xib이든 .nib이든 상관없이

보통 nib 파일이라고 부른다. 실제로 애플의 문서에서도 전체적으로 nib, nib 파일이라는 용

어를 사용하고 있다.

Xcode 4.x부터는 Hello_WorldViewController.xib을 Xcode 내에서 모두 편집할 수 있게 됐

다. 이 화면에서 왼쪽 영역의 Placeholders 아래에 있는 File’s Owner와 First Responder가 들어

있고, Objects 헤더 아래에는 View 아이콘이 들어 있음을 볼 수 있다. Objects 헤더 아래에 있는

모든 아이콘은 nib 파일이 로드될 때 자동으로 생성될 오브젝티브-C 클래스의 단일 인스턴스를

나타낸다. 예제 프로젝트에서 Objects 헤더 아래의 View 아이콘은 뷰 객체를 나타낸다.

버튼 인스턴스를 만들고 싶다면 물론 코드를 작성해 버튼을 생성해도 된다. 하지만 보통은 인

터페이스 빌더를 사용해 버튼을 생성하고 속성(모양, 크기, 라벨 등)을 지정하는 방식을 더 많이

사용한다.

지금 보고 있는 Hello_WorldViewController.xib 파일은 애플리케이션이 실행될 때 자동으로

로드된다(지금은 어떻게 해서 자동으로 로드되는지 고민하지 않아도 된다). 따라서 이 파일은

사용자 인터페이스를 구성할 객체를 생성하기에 더 없이 좋은 파일이다.

예를 들어 애플리케이션에 버튼을 추가하려면 UIButton 타입의 객체 인스턴스를 생성해야 한

다. 이 작업을 코드로 하려면 다음 코드 줄을 입력해야 한다.

UIButton *myButton = [[UIButton alloc] initWithFrame:aRect];

인터페이스 빌더에서는 인터페이스 객체 팔레트에서 버튼을 드래그해 뷰 창에 드롭하면 같은

일을 쉽게 할 수 있다. 인터페이스 빌더에서는 버튼의 속성도 쉽게 설정할 수 있다. 이렇게 추가한

버튼은 nib 파일에 저장된 후 애플리케이션이 실행될 때 자동으로 인스턴스가 생성된다. 이 부분

이 실제로 동작하는 과정은 잠시 후 보게 될 것이다.

Page 49: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 25

Nib 파일에 포함된 내용

그림 2-5를 다시 보자. 앞에서 언급한 것처럼 nib 파일을 처음 생성하면 File’s Owner와 First

Responder의 두 아이콘부터 생성된다. 이들 파일은 자동으로 생성되며 삭제할 수 없다. 이 점을

보면 이들 파일이 중요할 것이라 짐작할 수 있는데 실제로 두 파일은 매우 중요하다.

File’s Owner는 모든 nib 파일의 첫 번째 아이콘으로서 디스크에서 nib 파일을 로드한 객체를

나타낸다. 다른 식으로 표현하지만 File’s Owner는 이 nib 파일을 ‘소유’하는 객체다. 이런 설명이

잘 이해가 되지 않더라도 걱정할 필요가 없다. 지금 당장은 File’s Owner가 크게 중요하지 않기

때문이다. 나중에 File’s Owner가 더 중요해질 시점이 되면 그때 가서 다시 자세히 설명할 것이다.

nib 파일에 들어 있는 두 번째 아이콘은 퍼스트 리스폰더(First Responder)라고 부른다. 리스폰

더에 대해서는 이 책에서 나중에 다시 설명하겠지만, 간단히 말해 퍼스트 리스폰더는 사용자와

현재 상호작용 중인 객체를 말한다. 예를 들어 사용자가 텍스트 필드에 데이터를 입력 중이라면,

이 텍스트 필드가 퍼스트 리스폰더다. 퍼스트 리스폰더는 사용자가 UI와 상호작용하는 과정에

서 바뀌며 First Responder 아이콘을 활용하면 현재 퍼스트 리스폰더인 컨트롤이나 뷰를 판단

하는 코드를 작성하지 않아도 현재 퍼스트 리스폰더와 손쉽게 연동할 수 있다. 거듭 말하지만 이

내용은 나중에 자세히 설명할 것이므로 지금 바로 이해가 되지 않더라도 걱정하지 않아도 된다.

이들 두 아이콘을 제외한 나머지 아이콘은 nib 파일이 로드될 때 생성할 객체 인스턴스를 나

타낸다. 책의 예제에서는 그림 2-5에 보이는 것처럼 세 번째 아이콘이 View로 돼 있다.

View 아이콘은 UIView 클래스의 인스턴스를 나타낸다. UIView 객체는 사용자가 볼 수 있고

상호작용할 수 있는 영역이다. 이 애플리케이션에서는 하나의 뷰만 사용하므로 이 아이콘은 사

용자가 애플리케이션에서 볼 수 있는 전체 화면을 나타낸다. 이 책에서는 나중에 둘 이상의 뷰를

사용하는 복잡한 애플리케이션을 만들 것이지만 지금은 이 아이콘을 애플리케이션이 실행될 때

사용자가 볼 수 있는 내용 정도로 생각해도 된다.

노트

엄밀히 말해서 이 애플리케이션에서 뷰는 한 개보다 많다. 화면에 표시될 수 있는 버튼, 텍스

트 필드, 라벨 같은 UI 요소들은 모두 UIView의 하위 클래스다. 하지만 이 책에서 뷰라는 용

어는 보통 실제 UIView의 인스턴스만을 나타내는 용도로 사용하며, 이 애플리케이션의 경우

이런 뷰는 단 한 개뿐이다.

Page 50: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

26 l 시작하세요! 아이폰 4 프로그래밍

그림 2-5를 다시 보면 아이콘 우측으로 창이 하나 열려 있는 게 보일 것이다. 이 창은 Objects

영역에 들어 있는 아이콘을 그래픽 형태로 표현한 것이다. 이 창을 닫고 Objects 영역에서 View

아이콘을 클릭하면 이 창이 다시 열린다. 이 창은 UI를 그래픽적으로 디자인할 수 있는 창이다.

이제 작업을 바로 시작해 보자.

그림 2-5 | 인터페이스 빌더의 Hello_WorldViewController.xib

뷰에 라벨 추가하기

그림 2-5에서 가장 우측에 있는 영역은 유틸리티 영역이다. 라이브러리의 하단에는 라이브러리

가 들어 있다 이 창의 상세 화면은 그림 2-6에 나와 있다. 라이브러리에는 인터페이스 빌더에서

지원하는 코코아 터치 객체들이 나와 있다. 라이브러리에서 nib 파일 창으로 항목을 드래그하

면 애플리케이션에 해당 클래스의 인스턴스를 추가할 수 있다. 라이브러리 창을 보이게 하려면

View Utilities Object Library를 선택하거나 z3 단축키를 사용하면 된다. 이 팔레트에 들

어 있는 항목들은 주로 iOS UIKit에 속한다. iOS UIKit은 애플리케이션의 UI를 생성하는 데 사

용되는 객체들로 구성된 프레임워크다.

Page 51: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 27

코코아 터치에서 UIKit은 코코아의 AppKit과 같은 역

할을 한다. 두 프레임워크 모두 개념은 비슷하지만 사용

되는 플렛폼의 차이로 인해 두 프레임워크에는 많은 차이

점이 있다. 하지만 이들 프레임워크와 달리 NSString과

NSArray 같은 Foundation 프레임워크 클래스들은 코코

아와 코코아 터치 모두에서 함께 사용한다.

Label 항목은 라이브러리 영역에서 가장 첫 번째 항목

에 들어 있다(그림 2-6 참고).

Label은 iOS 기기의 화면에 텍스트를 표시할 수는 있

지만 사용자가 직접 수정할 수는 없는 텍스트를 나타낸

다. Label은 잠시 후 뷰에 추가할 것이다.

UI 객체들은 계층 구조를 가지므로 여기서는 라벨을

(View라고 부르는) 메인 뷰의 하위 뷰로 추가할 것이다.

인터페이스 빌더는 이런 뷰 계층 구조를 효율적으로 관

리한다. 객체에서 하위 뷰를 받아들이지 못하면 이 객체

위에 다른 객체를 드래그하지 못하게 한다.

라이브러리에서 라벨을 드래그해 View라는 뷰에 추가

하면 UILabel 인스턴스가 애플리케이션의 메인 뷰의 하

위 뷰로 추가된다.

라이브러리에 들어 있는 객체 목록에서 Label을 못찾겠다면 라이브러리 하단에 있는 검색 필

드에서 label을 입력해 보자. 입력 과정에서 검색 용어와 일치하는 객체들만 남고 나머지 객

체들은 모두 사라질 것이다. 검색이 끝난 후에는 전체 객체 목록이 다시 나타나게끔 검색 필드

를 원래대로 비워놓자.

라이브러리에서 View 창으로 Label을 드래그한다. 이렇게 하면 뷰가 그림 2-7 같은 형태로 보

일 것이다.

그림 2-6 | 인터페이스 빌더에서 사

용할 수 있는 UIKit의 객체들이 나와 있

는 라이브러리 영역

Page 52: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

28 l 시작하세요! 아이폰 4 프로그래밍

그림 2-7 | 애플리케이션의 View 창에 라벨을 추가한 모습

이번에는 라벨을 수정해 의미를 부여해 보자. 방금 생성한 라벨을 더블클릭하고 Hello,

World! 텍스트를 입력한다. 이어서 화면상에서 원하는 위치로 라벨을 드래그한다.

이제 저장만 마치면 모든 작업이 끝난다. File Save를 선택해 파일을 저장한다.

Xcode에서 Product Run(또는 단축키 zR을 누름)을 선택한다. 이제 그림 2-8과 같이

Xcode에서 애플리케이션을 컴파일하고 아이폰 시뮬레이터에서 실행할 것이다.

그림 2-8 | 드디어 Hello World 프로그램을 아이폰 버전으로 완성했다!

Page 53: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 29

첫 애플리케이션을 만들었다는 벅찬 감동이 어느 정도 진정되면 시뮬레이터를 종료시키자.

Xcode와 시뮬레이터는 별도의 응용 프로그램으로 돼 있다.

주의

빌드 및 실행 시점에 iOS 기기가 맥과 연결된 경우에는 애플리케이션 실행이 지금까지의 계획

과는 조금 다르게 진행된다. 간단히 말해 애플리케이션을 빌드해 아이폰상에서 실행하려면 먼

저 애플의 iOS 개발자 프로그램을 유료로 등록해야 하고 Xcode를 적절히 설정하는 과정을 모

두 거쳐야 한다. 개발자 프로그램에 등록하면 애플에서는 이 과정에 필요한 정보를 개발자들

에게 전송해준다. 하지만 개발자 등록 승인이 나기 전에는 책의 대다수 프로그램을 그냥 iOS

시뮬레이터에서 실행하더라도 괜찮다. 이 경우 iOS 기기가 맥과 연결돼 있다면 Run을 선택하

기 전에 Product Edit Schema에서 Destination을 선택하면 된다.

잠시만! 이게 끝이라니? 아직 코드를 한 줄도 쓰지 않았는데.

그렇다. 이처럼 아이폰 개발은 무척이나 간단하다.

그런데 텍스트 크기나 색상 같은 라벨의 속성을 변경하고 싶다면 어떻게 해야 할까? 이때는 코

드를 써야 할까?

이 역시 대답은 ‘아니오’다.

속성의 변경

뷰 창에서 Hello World 라벨을 한 번만 클릭해 라벨을 선택한다. 이어서 z4 단축키를 누르거

나 View Utilities Attribute Inspector를 선택한다. 이렇게 하면 현재 선택된 항목의 속성을

설정할 수 있는 어트리뷰트 인스펙터 영역이 우측에 나타난다(그림 2-9).

인스펙터에서는 폰트 크기, 색상, 드롭 섀도우 같은 다양한 사항을 변경할 수 있다. 인스펙터는

각 상황을 잘 인지한다. 예를 들어 텍스트 필드를 선택한 상황에서는 텍스트 필드에서 수정할 수

있는 속성들이 표시되고, 버튼을 선택한 상황에서는 버튼에서 수정할 수 있는 속성들이 표시되

는 식이다.

Page 54: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

30 l 시작하세요! 아이폰 4 프로그래밍

그림 2-9 | 라벨의 속성을 보여주는 어트리뷰트 인스펙터 영역

그럼 이어서 원하는 형태대로 라벨의 모양을 바꾼 후 저장하고 다시 Run을 선택하자. 이번에

도 코드 한 줄 작성하지 않고도 수정한 내용들이 애플리케이션에 보일 것이다. Xcode에서는 직

접 인터페이스를 그래픽적으로 디자인할 수 있게 해줌으로써 개발자들이 UI를 구성하는 코드

를 반복해서 작성하지 않고 애플리케이션에 꼭 필요한 코드만을 작성할 수 있게 한다.

노트

객체의 속성에 해당하는 각 필드의 의미를 모른다고 걱정할 필요도 없고 수정한 내용 중 일부

가 보이지 않는다고 해서 조바심 낼 필요도 없다. 책의 내용을 따라오다 보면 어트리뷰트 인스

펙터는 물론 각 필드가 하는 일에 대해 자세히 배우게 될 것이다.

대다수 현대 애플리케이션 개발 환경은 UI를 그래픽적으로 개발할 수 있는 도구를 제공한다.

Xcode의 인터페이스 빌더와 이런 개발 도구들 사이의 한 가지 차이점은 인터페이스 빌더에서는

별도 관리해야 하는 코드를 전혀 생성하지 않는다는 점이다. 대신 인터페이스 빌더는 코드에서

Page 55: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 31

하는 방식대로 오브젝티브-C 객체를 생성하고 이들 객체를 nib 파일로 직렬화함으로써, 런타임

시에 객체가 메모리에 직접 로드되게 한다. 이 방식은 코드 자동 생성과 관련한 많은 문제를 겪지

않게 해주고 전반적으로 더욱 강력한 개발 접근 방식이라고 할 수 있다.

아이폰 다듬기 — 화룡점정

이 장을 끝마치기 전에 마지막으로 진정한 iOS 애플리케이션의 느낌이 나도록 애플리케이션에

기름칠을 하고 광을 내보자. 먼저 프로젝트를 실행한다. 시뮬레이터 창이 나타나면 아이폰 시뮬

레이터의 홈 버튼을 클릭한다. 홈 버튼은 시뮬레이터 창의 최하단에 있는 흰색 사각형이 들어 있

는 검은색 버튼이다. 홈 버튼을 누르면 아이폰 홈 화면으로 이동하게 될 것이다(그림 2-10 참고).

잠시 애플리케이션을 살펴보자. 아직까지는 별로 볼 게 없을 것이다.

그림 2-10 | Hello World 애플리케이션의 아이콘이 밋밋해 보인다.

화면 상단에 있는 Hello World 아이콘을 살펴보자. 이 정도 아이콘으로는 좀 밋밋할 것 같다

는 생각이 들 것이다. 아이콘 디자인 문제를 해결하려면 아이콘을 생성한 후 PNG 파일 형태로

저장해야 한다. 이 파일의 크기는 57×57 픽셀 크기다. 이때 아이폰에 이미 들어 있는 기존 버튼

의 스타일과 꼭 맞추려고 하면 안 된다. 아이폰에서 자동으로 모서리를 둥글게 만들고 멋진 광택

효과를 아이콘에 부여하기 때문이다. 따라서 아이콘은 일반적인 사각형의 평평한 이미지 형태로

만들면 된다. 직접 아이콘을 만들고 싶지 않다면 프로젝트의 압축 파일(02 Hello World 폴더 내

에 들어 있다)에 들어 있는 아이콘 이미지를 사용해도 된다.

Page 56: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

32 l 시작하세요! 아이폰 4 프로그래밍

노트

애플리케이션의 아이콘은 의무적으로 .png 파일을 사용해야 하지만, iOS 프로젝트에 추가하

는 이미지 형식도 항상 .png 파일을 사용하는 게 좋다. 물론 대부분의 일반 이미지 형식이 제

대로 보이기는 하지만 다른 이미지 형식을 꼭 사용해야 하는 상황이 아니라면 .png 파일을 사

용하는 게 좋다. Xcode에서는 빌드 시점에 자동으로 .png 이미지를 최적화해주므로 .png 파

일은 iOS 애플리케이션에서 가장 빠르고 효과적으로 사용할 수 있는 이미지 형식이다.

애플리케이션의 아이콘을 디자인한 후에는 그림 2-11과 같이 Finder에서 .png 파일을 드래그

해 Xcode의 Supporting Files 폴더에 추가하거나 Xcode에서 Supporting Files 폴더를 마우스

오른쪽 선택한 후 Add Files To Hello World를 선택해 아이콘 이미지 파일 경로를 찾는다.

아이콘을 직접 디자인하지 않은 경우에는 책의 프로젝트 압축 파일을 찾은 다음 02 – Hello

World 폴더로 이동하면 프로젝트에 추가할 수 있는 아이콘 파일을 찾을 수 있다. 이 아이콘 파일

의 이름은 icon.png다. 이 파일을 찾아서 프로젝트의 Supporting Files 폴더에 드래그한다.

그림 2-11 | Xcode 프로젝트의 Supporting Files 폴더로 아이콘 파일을 드래그하는 모습

이렇게 하고 나면 Xcode에서 몇 가지를 묻는 새로운 대화상자를 띄울 것이다(그림 2-12 참고).

이때 Xcode에서 파일을 프로젝트 디렉터리로 복사하는 옵션을 선택하거나 원본 파일에 대한 참

Page 57: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 33

조를 프로젝트에 추가하는 옵션을 선택할 수 있다. 보통은 파일을 다른 프로젝트와 공유하지 않

는 한 Xcode 프로젝트에 파일을 복사하는 게 더 좋다.

그림 2-12 | 프로젝트에 파일을 추가하는 방법을 묻는 대화상자. 프로젝트에 추가항 항목은 항상 복사하는

게 좋다.

프로젝트에 일반적인 형태의 파일을 추가할 경우 Xcode는 그 파일을 어떻게 처리할지 이미 잘

알고 있다. 이로 인해 이 이미지 파일도 추가로 별도 작업을 하지 않더라도 자동으로 애플리케이

션이 컴파일될 때 함께 포함된다.

지금까지 한 작업은 icon.png 파일을 프로젝트에 추가하고, 이를 통해 아이콘 이미지가 애플리

케이션 번들에 포함되게 했다. 다음으로 할 일은 애플리케이션의 아이콘으로 사용할 특정 이미

지를 지정하는 것이다.

Xcode 프로젝트 창의 그룹 & 파일 영역에서 Support ing Fi les 폴더가 닫혀 있다면

Supporting Files를 펼치고 Hello World-Info.plist 파일을 한 번 클릭해 보자. 이 파일은 프로퍼

티 리스트(property list) 파일로서 아이콘 파일명을 비롯한 애플리케이션 관련 일반 정보를 보관

한다.

Hello_World-Info.plist 파일을 선택하면 편집 영역에 속성 목록이 보일 것이다(그림 2-13 참

고). 프로퍼티 리스트의 왼쪽 컬럼에서 Icon �le이라는 라벨이 들어 있는 행을 찾는다. 이 행의

우측 컬럼은 현재 비어 있을 것이다. 비어 있는 우측 셀을 더블클릭하고 프로젝트에 추가한 .png

파일의 이름을 입력한다.

Page 58: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

34 l 시작하세요! 아이폰 4 프로그래밍

노트

plist에서 Icon file 입력값을 무시하더라도 어쨌든 아이콘은 보인다. 왜 그럴까? 그 이유는 아

이콘 파일이 없을 경우, 기본적으로 SDK에서 icon.png라는 이름의 자원을 찾아서 이를 아이

콘 파일로 사용하기 때문이다. 이 내용은 독자들이 궁금할 것 같아 그냥 알려줬다.

그림 2-13 | 아이콘 파일의 지정

컴파일과 실행 준비 완료

애플리케이션을 컴파일하고 실행하기 전에 Hello_World-Info.plist에 있는 다른 행들을 살펴보

자. 대부분의 설정은 현재 있는 그대로 사용해도 되지만 이 중 한 가지 설정은 좀 주의를 요한다.

바로 번들 식별자(Bundle identi�er)에 대한 부분이다. 이 식별자는 애플리케이션에 대한 고유 식

별자로서 항상 설정해야 한다. 단지 iOS 시뮬레이터에서만 애플리케이션을 실행할 생각이라면

표준 명명 관례에 따라 com이나 org 같은 최상위 레벨의 인터넷 도메인 이후에 점을 사용하고,

이어서 애플리케이션명을 추가한 이름을 번들 식별자로 사용하면 된다. 실제 iOS 기기에서 애플

리케이션을 실행할 생각이라면 애플리케이션의 번들 식별자를 만드는 과정이 좀 더 복잡한데,

이 과정은 iPhone SDK Program에 유료로 등록한 경우 아이폰 프로그램 포탈을 통해 확인할

수 있다. 번들 식별자를 apress로 설정한다. 이 문자열의 마지막에 있는 값은 특수 코드로서 애플

리케이션이 빌드될 때 애플리케이션명으로 대체되며, 이를 통해 애플리케이션의 번들 식별자는

애플리케이션의 이름과 관련한 식별자를 갖게 된다.

번들 식별자까지 설정했다면 애플리케이션을 컴파일하고 실행하자. 시뮬레이터가 구동을 마

치면 홈 버튼을 클릭해 홈으로 이동하고 새로 수정한 아이콘을 확인하자. 책에서 제공한 예제 아

이콘은 그림 2-14에 나와 있다.

Page 59: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 35

그림 2-14 | 이제 애플리케이션 아이콘이 세련되게 바뀌었다!

그림 2-14에서는 기본 아이콘이 들어 있는 Hello World 애플리케이션과 새 아이콘이 적용된

Hello World 애플리케이션이 따로 설치된 것을 볼 수 있다. 왜 이렇게 됐을까? 이렇게 된 이유는

조금 전에 수정한 번들 식별자로 인해 애플리케이션에 대한 고유 식별자가 변경됐기 때문이다.

yourcompany를 apress로 바꾸는 과정에서 iOS에게 이 애플리케이션은 기존 애플리케이션과

는 다른 애플리케이션이라고 알려준 것이다.

노트

아이폰 시뮬레이터의 홈 화면에서 기존 애플리케이션을 제거하려면 홈 디렉터리의 라이브러

리 폴더에 들어 있는 Application Support 폴더에서 iPhone Simulator라는 폴더를 삭제하

면 된다. 또는 iOS Simulator Reset Content and Settings…를 선택하더라도 시뮬레이

터를 재설정할 수 있다.

Page 60: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

36 l 시작하세요! 아이폰 4 프로그래밍

정리하며...

자신의 어깨를 한 번씩 토닥여주자. 이 장에서 그다지 한 일이 많지 않아 보일 수도 있지만 실제

로는 꽤 많은 내용을 다뤘다. 이 장에서는 iOS 프로젝트 템플릿에 대해서 배웠고 애플리케이션

을 생성해 봤으며 인터페이스 빌더를 사용하는 법을 살펴보고 애플리케이션 아이콘과 번들 식별

자를 설정하는 법도 배웠다.

하지만 Hello World 애플리케이션은 전형적인 단방향 애플리케이션이다. 사용자에게 정보를

보여주긴 하지만 사용자로부터의 입력은 기대할 수 없다. iOS 기기의 사용자로부터 입력을 받고

사용자의 입력에 따라 행동을 취하는 법을 배울 준비가 됐다는 생각이 들면 호흡을 크게 한번

들이쉬고 다음 페이지로 페이지를 넘기자.

Page 61: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

02 티키 신 달래기 l 37

Page 62: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

Beg

inni

ng iP

hone

4

Dev

elop

men

t

Page 63: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

39

03기본적인 상호작용의 처리

Hello World 애플리케이션은 코코아 터치를 활용해 iOS 애플리케이션을 개발하는 법을 소개하

기에는 딱 좋은 예제였지만 핵심 기능 한 가지가 빠져 있다. 사용자와 상호작용할 수 있는 기능이

없는 것이다. 사용자와의 상호작용이 없다면 애플리케이션의 활용 범위가 크게 제한될 수밖에

없다.

이 장에서는 그림 3-1과 같이 라벨은 물론 두 개의 버튼도 들어 있는 조금 더 복잡한 애플리케

이션을 개발한다. 사용자가 두 버튼 중 하나를 탭하면 라벨의 텍스트가 바뀐다. 이 애플리케이션

예제도 마찬가지로 간단해 보이기는 하지만 이 예제에는 iOS 애플리케이션에서 사용자와의 상

호작용을 구현하는 데 필요한 핵심 개념들이 담겨 있다.

그림 3-1 | 두 개의 버튼이 들어 있는 간단한 애플리케이션. 이 장에서는 이 애플리케이션을 개발한다.

Page 64: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

40 l 시작하세요! 아이폰 4 프로그래밍

모델-뷰-컨트롤러 패러다임

내용에 들어가기 앞서 잠깐 이론을 살펴보겠다. 코코아 터치의 설계자들은 모델-뷰-컨트롤러

(MVC)라는 개념을 기반으로 코코아 터치를 설계했다. MVC는 GUI 기반의 애플리케이션을 구

성하는 코드를 서로 분리시키는 매우 논리적인 설계다. 오늘날 거의 모든 객체 지향 프레임워크

가 어느 정도는 MVC 패턴을 구현하고 있지만 코코아 터치만큼 MVC 모델을 충실히 따르는 프

레임워크는 거의 없다.

MVC 패턴은 기능을 세 개의 각기 다른 범주로 구분한다.

▶ 모델 : 애플리케이션의 데이터를 보관하는 클래스

▶ 뷰 : 창, 컨트롤, 기타 사용자가 볼 수 있고 상호작용할 수 있는 UI 요소로 구성

▶ 컨트롤러 : 모델과 뷰를 한데 묶고 사용자의 입력을 어떻게 처리할지 결정하는 애플리케

이션 로직

MVC 패턴의 목적은 이들 세 종류의 코드를 구현하는 객체들을 가능한 한 서로 따로 떼어내

는 것이다. MVC 패턴에서는 객체가 세 범주 중 어느 곳에 속하는지 바로 식별할 수 있어야 하며,

객체는 자신이 속한 범주 이외의 다른 범주에 속한 기능을 거의 갖지 않거나 전혀 갖지 않아야

한다. 예를 들어 버튼을 구현하는 객체는 사용자가 버튼을 탭했을 때 데이터를 처리하는 코드를

포함하지 않아야 하며, 은행 계좌를 구현한 객체는 은행 거래 내역을 보여주는 표를 그리는 로직

을 포함하지 않아야 한다.

MVC를 활용하면 재사용성을 극대화하는 데 도움이 된다. 일반적인 버튼을 구현한 클래스는

모든 애플리케이션에서 그대로 사용할 수 있다. 하지만 버튼을 클릭했을 때 특정 연산을 수행하

는 클래스는 본래 이 클래스를 사용하려고 한 애플리케이션에서만 사용할 수 있다.

코코아 터치 애플리케이션을 개발할 때는 가끔씩 코드를 통해 인터페이스를 수정하기도 하고

기존 뷰나 컨트롤의 하위 클래스를 구현하기도 하지만, 주로 인터페이스 빌더를 사용해 뷰 컴포

넌트를 생성한다.

모델은 애플리케이션의 데이터를 보관할 오브젝티브-C 클래스를 구현하거나 12장에서 배울

코어 데이터를 활용해 데이터 모델을 만드는 형태로 구현한다. 이 장의 애플리케이션에서는 별도

로 저장하거나 보관할 데이터가 없으므로 모델 객체는 만들지 않겠지만, 이후 장에서 애플리케

이션이 점차 복잡해지면 모델 객체에 대해서도 자세히 소개하겠다.

Page 65: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 41

컨트롤러 컴포넌트는 주로 애플리케이션과 관련해 생성하는 클래스들로 구성된다. 컨트롤러

는 완전한 커스텀 클래스(NSObject의 하위 클래스)로 만들 수도 있지만 보통은 UIKit 프레임

워크의 UIViewController 같은 기존 컨트롤러 클래스를 상속한 하위 클래스 형태로 구현한다.

UIViewController는 다음 절에서 살펴본다. 이들 기존 클래스를 상속하면 수많은 기능을 바로

쓸 수 있으므로 복잡한 로직을 처음부터 다시 만들지 않아도 돼서 편하다.

코코아 터치를 좀 더 배우다 보면 금세 UIKit 프레임워크의 클래스들이 어떻게 연동해 MVC

원칙을 고수하는지 이해가 될 것이다. 개발을 진행하면서 머릿속에 이 원칙을 잘 정리해 둔다면

훨씬 더 깔끔하고 유지보수하기 쉬운 코드를 작성할 수 있을 것이다.

프로젝트의 생성

이제 다음 번 Xcode 프로젝트를 생성할 차례다. 이 장에서도 이전 장과 같은 템플릿을 활용해 프

로젝트를 생성한다. 즉 View-based Application 템플릿을 활용하는 것이다. 이 템플릿을 기반

으로 프로젝트를 생성하면 뷰와 컨트롤러 객체가 iOS 애플리케이션에서 어떻게 연동하는지 쉽

게 알 수 있다. 나머지 템플릿들은 이후 장들에서 사용할 예정이다.

이제 프로젝트를 생성하고 Device Family 팝업 메뉴에서 iPhone을 선택한 후 Button Fun이

라는 프로젝트명으로 프로젝트를 저장하자. 프로젝트를 만드는 과정에서 문제가 생긴다면 앞 장

에서 적절한 절차 설명을 참고하기 바란다.

프로젝트 템플릿에서 자동으로 일부 클래스를 생성해준다는 사실을 기억할 것이다. 이들 클

래스는 새로 생성한 프로젝트 내에서 찾아볼 수 있는데, 일부 클래스의 경우 프로젝트명을 기반

으로 클래스명이 정해지므로 클래스명이 이전 장과 비교해 조금 다를 수 있다.

뷰 컨트롤러의 생성

이 장에서는 잠시 후 이전 장에서 한 것처럼 인터페이스 빌더를 활용해 애플리케이션에 대한 뷰

(또는 사용자 인터페이스)를 디자인할 것이다. 하지만 그 전에 자동으로 생성된 소스 코드 파일

을 몇 개 살펴보고 내용을 수정해 보겠다. 그렇다. 드디어 이 장에서 최초로 코드 작성을 시작해

보는 것이다.

코드를 수정하기 전에 먼저 자동으로 생성된 파일들을 살펴보자. 그룹 & 파일 영역에서

Button_Fun 폴더를 펼치면 그림 3-2와 같이 안에 여섯 개의 파일이 들어 있을 것이다.

Page 66: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

42 l 시작하세요! 아이폰 4 프로그래밍

그림 3-2 | 프로젝트 템플릿에서 자동으로 생성해준 파일들을 보여주는 그룹 & 파일 영역. 이때 클래스 파

일명에 프로젝트명이 포함되는 것을 확인하자.

이 중 .xib 파일을 제외한 네 파일은 각각 .m과 .h 파일을 포함하는 두 개의 클래스를 구현

한다. 이 장에서 개발할 애플리케이션은 뷰가 하나뿐이며, 이 뷰를 관리할 컨트롤러 클래스는

Button_FunViewController다. 이 컨트롤러의 클래스명에서 Button_Fun 부분은 프로젝트명

에서 온 것이며 클래스명에서 ViewController 부분은 이 클래스가 뷰 컨트롤러임을 나타낸다.

그룹 & 파일 영역에서 Button_FunView Controller.h를 클릭하고 이 파일의 내용을 살펴보자.

#import <UIKit/UIKit.h>

@interface Button_FunViewController : UIViewController {

}

@end

안에 내용이 별로 없음을 볼 수 있을 것이다. Button_FunViewController는 앞에서 언급한

일반 컨트롤러 클래스 중 하나인 UIViewController의 하위 클래스다. UIViewController는

UIKit 프레임워크에 속하며 수많은 기능을 기본으로 제공한다. 컨트롤러가 애플리케이션에서

담당할 구체적인 기능을 Xcode가 알 수는 없지만, Xcode에서는 적어도 애플리케이션에 컨트롤

러가 필요할 것이라는 사실은 알고 있으므로 Xcode는 이런 기능을 담당할 클래스를 자동으로

생성해준다.

그림 3-1을 다시 보자. 이 애플리케이션은 두 개의 버튼과 사용자가 탭한 버튼의 내용을 반영

할 텍스트 라벨로 구성된다. 이들 세 UI 요소는 모두 인터페이스 빌더에서 생성한다. 이 장에서

는 코드를 작성할 예정이므로 인터페이스 빌더에서 생성하는 UI 요소와 코드가 상호작용할 수

있어야 한다.

물론 당연히 인터페이스 빌더와 코드가 상호작용하게 할 수 있는 방법이 있다. 컨트롤러 클래

스는 아웃렛(outlet)이라고 하는 특수한 인스턴스 변수를 사용해 nib 파일에 있는 객체를 참조

Page 67: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 43

할 수 있다. 아웃렛은 nib 파일 내에 있는 객체를 가리키는 포인터 정도로 생각하면 쉽다. 예를

들어 인터페이스 빌더에서 텍스트 라벨을 생성한 후 코드 내에서 라벨의 텍스트를 변경한다고

가정하자. 아웃렛을 선언하고 해당 아웃렛을 라벨 객체와 연결하면, 코드 내에서 아웃렛을 활용

해 라벨에 보이는 텍스트를 변경할 수 있다. 이를 어떻게 구현하는 지는 이 장에서 잠시 후 보게

될 것이다.

반대로 nib 파일에 있는 인터페이스 객체들이 컨트롤러 클래스에 있는 특수 메서드를 호출하

게끔 설정할 수도 있다. 이러한 특수 메서드는 액션 메서드라고 부른다. 예를 들어 사용자가 버튼

에서 손을 떼면(화면을 터치한 손가락을 떼어내면) 코드에 들어 있는 특수 액션 메서드를 실행하

도록 인터페이스 빌더에서 지정할 수 있다.

이 장에서 작성할 코드에서는 라벨을 가리키는 아웃렛을 생성하고 이 아웃렛을 활용해 라벨

의 텍스트를 변경한다. 또 두 버튼 중 하나를 탭할 때마다 호출할 buttonPressed:라는 메서드도

작성한다. buttonPressed:는 사용자가 버튼이 탭됐음을 알 수 있게 라벨의 텍스트를 설정하는

일을 한다.

이 장에서는 인터페이스 빌더를 활용해 버튼과 라벨을 생성한 후 클릭과 드래그를 통해 라벨

을 라벨 아웃렛과 연결하고 버튼을 buttonPressed: 액션과 연결할 것이다.

하지만 코드 작성에 앞서 아웃렛과 액션을 좀 더 자세히 살펴볼 필요가 있다.

아웃렛

아웃렛은 IBOutlet이라는 키워드를 사용해 선언하는 인스턴스 변수다. 컨트롤러 헤더 파일에서

아웃렛을 선언하는 코드는 다음과 같다.

@property (nonatomic, retain) IBOutlet UIButton *myButton;

IBOutlet 키워드는 다음과 같이 정의한다.

#ifndef IBOutlet

#define IBOutlet

#endif

잘 이해가 안 된다면 이런 식으로 이해하자. IBOutlet은 컴파일러와 관련해서는 아무 일도 하

지 않는다. 아웃렛의 목적은 아웃렛이 nib 파일에 있는 객체와 연결할 인스턴스 변수라는 사실

을 인터페이스 빌더에게 알려주는 것뿐이다. nib 파일에 있는 객체와 연결할 목적으로 생성하는

인스턴스 변수 앞에는 항상 IBOutlet 키워드를 사용해야 한다. 그룹 & 파일 영역에서 nib 파일을

Page 68: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

44 l 시작하세요! 아이폰 4 프로그래밍

열면 인터페이스 빌더에서는 프로젝트 헤더 파일에서 이 키워드가 사용된 곳을 모두 검사하고

이들 변수를 통해(서만) 코드가 nib 파일과 연계할 수 있게 한다. 이 장에서 나중에 살펴볼 ‘아웃

렛 연결’ 절에서는 실제 아웃렛과 인터페이스 빌더의 UI 객체를 연결하는 법을 보게 될 것이다.

아웃렛의 위치 변경

이 책의 초판에서는 다음과 같이 IBOutlet 키워드를 인스턴스 변수 선언 앞에 두었다.

IBOutlet UIButton *myButton;

이후 애플의 모범 예제 코드는 다음과 같이 IBOutlet 키워드를 속성 선언쪽에 배치하는 형태

로 바뀌었다.

@property (nonatomic, retain) IBOutlet UIButton *myButton;

두 방식이 모두 지원되며 대부분의 경우 이 키워드를 지정하는 위치는 동작 방식에 전혀 영향

을 주지 않는다. 하지만 한 가지 예외 상황도 있다. (@synthesize 지시어를 사용해) 속성을

내부 인스턴스 변수와 다른 이름으로 선언할 경우 속성이 제대로 동작하려면 인스턴스 변수

선언 앞이 아니라 항상 속성 선언 앞에 IBOutlet 키워드를 두어야 한다. 속성에 대한 개념이

잘 이해가 안 된다면 잠시 후 설명할 내용을 참고하면 된다.

두 방식 모두 사용할 수 있지만 이 책에서는 애플의 코딩 방식을 따라 모든 코드에서 IBOutlet

키워드를 속성 선언 앞에 두었다.

새로운 오브젝티브-C 속성에 대한 내용은 마크 달림플과 스콧 내스터가 집필한 Learn

Objective-C on the Mac(Apress, 2009)과 애플의 개발자 웹사이트에서 제공하는 오브젝

티브-C 프로그래밍 언어 소개(http://developer.apple.com/documentation/Cocoa/

Conceptual/ObjectiveC)를 참고하자.

액션

액션은 컨트롤러 클래스에 속한 메서드를 가리킨다. 액션은 IBAction이라는 특수 키워드를 사

용해 선언하는데, IBAction 키워드를 사용하면 인터페이스 빌더에서는 해당 메서드가 액션이라

는 것과 컨트롤에서 호출할 메서드라는 사실을 알게 된다. 보통 액션 메서드는 다음과 같이 선언

한다.

- (IBAction)doSomething:(id)sender;

액션 메서드의 이름은 원하는 대로 지정해도 되지만 항상 IBAction 타입을 반환해야 한다.

IBAction 타입은 void 반환 타입과 같은 타입이다. IBAction 반환 타입은 액션 메서드에서 값

Page 69: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 45

을 반환하지 않음을 알려주는 또 다른 방식일 뿐이다. 보통 액션 메서드는 주로 id 타입의 sender

라는 이름으로 선언된 한 개의 인자를 받는다. 액션을 호출하는 컨트롤은 sender 인자를 활용

해 자신에 대한 참조를 넘겨준다. 따라서 예컨대 버튼을 탭했을 때 호출되는 액션 메서드의 경우

sender 인자 값에는 사용자가 탭한 특정 버튼에 대한 참조가 들어 있다.

다음 절에서 보겠지만 이 장의 예제 프로그램에서도 sender 인자를 활용해 사용자가 탭한 버

튼 종류에 따라 라벨의 텍스트를 ‘le�’에서 ‘right’로 바꾼다. 액션 메서드를 호출한 컨트롤을 굳

이 알 필요가 없다면 액션 메서드를 sender 인자 없이 선언해도 된다. 이 경우 다음과 같이 액션

메서드를 선언한다.

- (IBAction)doSomething;

하지만 sender 인자를 액션 메서드에 일단 선언해 놓고 sender 인자를 무시하더라도 손해볼

일은 없다. 실제로 예제 코드 중 꽤 많은 코드가 일단 sender 인자를 선언해 놓고 이를 실제로 쓰

지 않고 있다. 이렇게 하는 이유는 전통적으로 코코아에서 액션 메서드는 인자를 사용하든 사용

하지 않든 항상 sender 인자를 받는 식으로 선언했기 때문이다.

뷰 컨트롤러에 액션과 아웃렛 추가

이제 아웃렛과 액션이 뭔지 알았으므로 액션과 아웃렛을 컨트롤러 클래스에 하나씩 추가해 보

자. 이 예제에서는 라벨의 텍스트를 변경하기 위해 아웃렛이 필요하다. 이 애플리케이션에서는

버튼의 내용은 바꾸지 않으므로 버튼에 대한 아웃렛은 선언하지 않아도 된다.

또 두 버튼에서 호출할 액션 메서드도 한 개 선언해야 한다. 보통 액션 메서드는 단일 컨트롤에

국한돼 사용하지만 하나의 액션으로 여러 컨트롤의 입력을 처리할 수도 있다. 이 장에서도 이 방

식을 사용한다. 이 액션 메서드에서는 sender 인자를 통해 버튼의 이름을 알아온 후 버튼의 이

름을 라벨 텍스트에 보여주기 위해 라벨 아웃렛을 활용한다. 이를 구현하는 구체적인 방법은 몇

페이지 후 buttonPressed: 메서드를 보면서 자세히 살펴볼 것이다.

노트

Xcode에서는 이미 코드가 어느 정도 들어 있는 클래스 파일들을 자동으로 생성해주므로 기존

파일에 코드를 삽입하는 경우가 많다. Button_FunViewController.h 같은 파일의 코드에서

일반 코드 폰트로 표기된 코드는 해당 파일에 원래 들어 있는 코드로 이해하면 된다. 독자들이

새로 입력할 코드는 예제에서 볼드체로 표기했다.

Page 70: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

46 l 시작하세요! 아이폰 4 프로그래밍

다음 코드를 Button_FunViewController.h에 작성하자.

#import <UIKit/UIKit.h>

@interface Button_FunViewController : UIViewController {

UILabel *statusText;

}

@property (nonatomic, retain) IBOutlet UILabel *statusText;

- (IBAction)buttonPressed:(id)sender;

@end

기존에 오브젝티브-C 2.0 언어를 사용해본 경험이 있다면 아마 @property 선언이 익숙할 테

지만 오브젝티브-C 언어를 사용해본 적이 없다면 이 코드가 다소 어렵게 느껴질 수도 있을 것이

다. 그렇지만 오브젝티브-C의 속성은 매우 단순하므로 걱정하지 않아도 된다. 이 책에서는 이들

속성을 꽤 많이 사용해야 하므로 간단히 오브젝티브-C 언어의 속성을 살펴보자. 속성을 이미 잘

알고 있더라도 다음 절의 내용을 계속 읽기 바란다. 코코아 터치와 관련한 정보도 들어 있으므로

많은 도움이 될 것이다.

오브젝티브-C 속성

오브젝티브-C에 속성이 추가되기 전에 프로그래머들은 클래스의 개별 인스턴스 변수를 설정하

고 조회하는 메서드 쌍을 모두 정의했다. 이들 메서드는 접근자, 수정자(또는 게터, 세터)라고 부

르며 다음과 같은 형태로 선언한다.

- (id)foo {

return foo;

}

- (void)setFoo:(id)aFoo {

if (aFoo != foo) {

[aFoo retain];

[foo release];

foo = aFoo;

}

}

물론 이 방식은 지금도 사용할 수 있지만 @property 선언의 도입으로 인해 이제는 접근자와

수정자 메서드를 귀찮게 선언하지 않아도 된다. @property 선언과 구현체 파일에서의 또 다른

선언(@synthesize 선언. 이 선언은 Button_FunViewController.m 파일을 수정할 때 보게 될 것

Page 71: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 47

이다)을 활용하면 컴파일러에게 컴파일 시점에 게터 및 세터 메서드를 생성하도록 명령할 수 있

다. 보통 속성을 선언할 때는 앞에서 한 것처럼 내부 인스턴스 변수를 선언하지만 접근자나 수정

자 메서드는 따로 정의하지 않아도 된다.

노트

앞 단락에서는 ‘보통’ 속성과 일치하는 인스턴스 변수를 선언한다고 말했다. 이 말은 듣기에

따라 내부 인스턴스 변수를 선언하지 않는 게 ‘비정상’인 듯한 느낌을 풍긴다. 사실 그렇다.

오브젝티브-C 2.0에서는 인스턴스 변수와 속성의 이름이 같으면 인스턴스 변수 선언을 생

략한 채 속성을 선언할 수 있다. 하지만 이 기능은 iOS와 맥 OS X 10.6 이후의 64비트 애플

리케이션 같은 애플에서 제공하는 최신 런타임 환경에서만 동작하고 맥 OS X의 32비트 애

플리케이션에서는 동작하지 않는다. 2010년 여름까지만 해도 아이폰 시뮬레이터에서 구동

중인 소프트웨어도 이를 지원하지 않았다. 모든 개발자가 어느 정도는 시뮬레이터를 활용하

므로, 인스턴스 변수를 생략한 코드를 기반으로 개발할 경우 지금까지 iOS로 작성된 거의 모

든 소프트웨어에서 인스턴스 변수를 포함시켜야 하므로 작업이 매우 번거롭다. 현재까지도

Xcode의 디버거는 인스턴스 변수가 선언되지 않은 속성에 대한 정보를 잘못 보여준다. 이

책에서는 대부분의 경우 인스턴스 변수를 함께 포함시킬 것이다. 하지만 iOS 개발 경력이 더

쌓이고 그 사이 개발 도구들도 발전하면 이런 인스턴스 변수도 과거의 유산처럼 느껴지는 날

이 오게 될 것이다.

이 선언에서 @property 키워드 다음에는 괄호로 감싼 선택 어트리뷰트들이 나온다. 이들 어트

리뷰트는 컴파일러가 생성할 접근자와 수정자를 정의하기 위한 것이며, 코드를 보는 프로그래머

에게 속성을 사용할 상황을 알려주는 역할도 한다. 이들 어트리뷰트는 객체가 인스턴스 변수를

어떻게 처리할지 지정한다. 다음에 나온 두 어트리뷰트는 아이폰 애플리케이션에서 속성을 정의

할 때 주로 사용하는 어트리뷰트다.

@property (retain, nonatomic) IBOutlet UILabel *statusText;

두 어트리뷰트 중 첫 번째 어트리뷰트인 retain은 이 속성에 대입한 객체에 대해 컴파일러가

retain 메시지를 보내게 한다. 이렇게 하면 속성에 사용된 내부 인스턴스 변수를 사용하는 중에

는 변수가 메모리에서 제거되지 않는다. 이 어트리뷰트를 지정해야 하는 이유는 기본값에 해당

하는 속성 선언 어트리뷰트(assign)의 용도 자체가 저수준 C 데이터 타입이나 현재 iOS 버전에서

지원하지 않은 가비지 컬렉션을 위한 것이기 때문이다. 따라서 (int 같은 원시 데이터 타입이 아

니라) 객체에 해당하는 속성을 정의하려면 보통 선택 어트리뷰트에서 retain을 지정해줘야 한다.

int나 �oat 또는 다른 원시 타입의 속성을 선언할 때는 선택 어트리뷰트를 선언하지 않아도 된다.

Page 72: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

48 l 시작하세요! 아이폰 4 프로그래밍

실제로 저수준 데이터 타입 속성에 대해 retain을 속성 선언에서 지정하면 에러가 발생한다. 오

브젝티브-C 객체에 해당하지 않는 데이터 타입에서는 메시지를 전혀 받을 수 없으므로 retain도

release도 할 수 없기 때문이다.

두 번째 선택 어트리뷰트인 nonatomic은 접근자와 수정자 메서드의 생성 방식을 지정한다. 지

나치게 기술적으로 설명하지 않고 요점만 간단히 설명하자면, 기본값을 적용할 경우 이들 메서

드는 다중 스레드 프로그램을 개발할 때 도움이 되는 추가 코드를 사용해 생성된다. 이런 추가적

인 코드 부담이 물론 크게 부담되지는 않지만, 사용자 인터페이스 객체에 대한 포인터를 선언할

때는 사실 전혀 필요 없다. 따라서 여기서는 nonatomic으로 어트리뷰트 값을 지정해 이런 추가

부담을 없앴다. 물론 속성에 대해 nonatomic을 지정하지 말아야 하는 경우도 있지만 보통 iOS

애플리케이션을 개발할 때는 nonatomic을 주로 사용한다.

오브젝티브-C 2.0에는 속성과 함께 사용할 수 있는 또 다른 멋진 기능이 있다. 바로 언어에서

점 표기법을 사용할 수 있는 것이다. 전통적인 접근자 메서드를 사용할 때는 다음과 같은 방식으

로 객체에 메시지를 보냈다.

myVar = [someObject foo];

물론 이 방식은 지금도 사용할 수 있다. 하지만 속성을 선언한 경우에는 자바나 C++, C# 등에

서 사용하는 것처럼 점 표기법을 사용해 메시지를 보낼 수도 있다.

myVar = someObject.foo;

앞의 두 명령문은 컴파일러와 관련해서는 똑같이 적용된다. 두 방식 중 원하는 방식을 그냥 사

용하면 된다. 점 표기법은 수정자에서도 사용할 수 있다. 아래 명령문은

someObject.foo = myVar;

다음 명령문과 기능상 동일하다

[someObject setFoo:myVar];

Page 73: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 49

노트

이 책에서는 속성을 처리할 때 다소 엄격한 원칙을 적용했다. 이 책에서는 속성이 선언된 인스

턴스 변수에 접근할 때는 메서드를 직접 호출하거나 점 표기법을 사용해 속성의 게터 및 세터

를 통해 변수에 접근한다. 동일 객체 내에서의 속성 참조의 경우 self.속성명 형태로 접근함으

로써 이 방식을 대체할 수도 있었지만 코드의 일관성과 (다른 객체들은 항상 속성명을 통해 접

근해야 하므로) 프로그램의 잘못된 부분을 쉽게 고치기 위해 (게터와 세터에는 잘못된 값이 잘

못 들어 있는 경우가 생길 수 있으므로) 모든 곳에서 속성을 사용하기로 했다. 이런 원칙을 적

용하지 않는 경우는 인스턴스 변수에 직접 접근하는 init과 dealloc 메서드가 유일하다. 이

들 메서드에서 인스턴스 변수에 직접 접근하는 이유는 해당 속성이 변화 상태(방금 생성됐거

나 제거될 상태)에 있으므로 이 시점에서는 게터나 세터를 호출하는 게 적절치 않기 때문이다.

Xcode의 템플릿에서 생성하는 애플의 코드에서는 이런 가이드라인을 따르지 않으므로 주의

하자. 하지만 이 책에서 추가할 코드는 항상 이 원칙을 고수한다.

액션 메서드의 선언

속성을 선언한 후에는 다음 코드를 추가한다.

- (IBAction)buttonPressed:(id)sender;

이 코드는 액션 메서드를 선언한 코드다. 이곳에 액션 메서드를 선언하면 다른 클래스들 및 인

터페이스 빌더에서는 이 클래스에 buttonPressed:라는 액션 메서드가 있다는 사실을 알게 된다.

구현체 파일에 액션과 아웃렛 추가

이제 한동안은 컨트롤러 클래스 헤더 파일은 수정할 일이 없으므로 저장해 두고, 이어서 클래스

의 구현체 파일인 Button_FunViewController.m을 클릭한다. 이 파일의 코드는 다음과 같이 돼

있을 것이다.

#import "Button_FunViewController.h"

@implementation Button_FunViewController

- (void)dealloc

{

[super dealloc];

}

- (void)didReceiveMemoryWarning

Page 74: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

50 l 시작하세요! 아이폰 4 프로그래밍

{

// 상위 뷰가 없는 경우 뷰를 릴리스한다.

[super didReceiveMemoryWarning];

// 사용하지 않는 캐시 데이터, 이미지 등을 릴리스한다.

}

#pragma mark - View lifecycle

/*

// nib 등으로부터 뷰를 로드한 후 추가 설정을 하기 위해 viewDidLoad를

// 구현한다.

- (void)viewDidLoad

{

[super viewDidLoad];

}

*/

- (void)viewDidUnload

{

[super viewDidUnload];

// 메인 뷰에서 참조 유지한 하위 뷰를 모두 릴리스한다.

// e.g. self.myOutlet = nil;

}

- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation

{

// 지원하는 방향에 대해 YES를 반환한다.

return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

@end

애플에서는 개발자들이 주로 오버라이드해야 할 메서드를 미리 예상하고 구현체 파일에 이들

메서드에 대한 스텁 함수를 포함시켰다. 메서드 중 일부는 주석 처리돼 있으며 필요에 따라 주석

을 해제해 구현하거나 아예 삭제할 수 있다. 주석 처리되지 않은 메서드들은 템플릿에서 사용하

는 메서드이거나 공통으로 사용되는 메서드로서 개발 시간을 줄여주기 위해 포함됐다. 이 애플

리케이션에서는 주석 처리된 메서드 중 사용할 만한 메서드가 없으므로 메서드를 모두 제거한

후, 필요한 코드만 있는 상태에서 새 코드를 파일에 추가하겠다.

Page 75: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 51

주석 처리된 메서드를 모두 제거한 후에는 다음 코드를 추가한다. 코드를 모두 추가하고 나면

추가한 코드에 대해서 하나씩 차례대로 설명하겠다.

#import "Button_FunViewController.h"

@implementation Button_FunViewController

@synthesize statusText;

- (IBAction)buttonPressed:(id)sender {

NSString *title = [sender titleForState:UIControlStateNormal];

NSString *newText = [[NSString alloc] initWithFormat:

@"%@ button pressed.", title];

statusText.text = newText;

[newText release];

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning]; // 상위 뷰가 없는 경우

// 뷰를 릴리스한다.

// 캐시 데이터 같은 핵심 데이터가 아닌 정보를 모두 릴리스한다.

}

- (void)viewDidUnload {

// 메인 뷰의 참조 유지한 하위 뷰를 모두 릴리스한다.

// e.g. self.myOutlet = nil;

self.statusText = nil;

}

- (void)dealloc {

[statusText release];

[super dealloc];

}

@end

이제 새로 추가된 코드를 하나씩 살펴보자. 먼저 다음 코드를 추가했다.

@synthesize statusText;

이 코드는 컴파일러에게 자동으로 접근자와 수정자 메서드를 생성하려고 명령하는 코드

다. 이 코드 덕분에 이 클래스에는 ‘보이지 않는’ 메서드가 두 개 추가된다. 바로 statusText와

setStatusText가 추가되는 것이다. 이들 메서드는 클래스에서 자동으로 생성하므로 직접 작성하

지 않아도 바로 사용할 수 있다.

Page 76: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

52 l 시작하세요! 아이폰 4 프로그래밍

다음으로 추가한 코드는 버튼을 탭할 때 호출할 액션 메서드의 구현체 코드다.

-(IBAction)buttonPressed: (id)sender {

NSString *title = [sender titleForState:UIControlStateNormal];

NSString *newText = [[NSString alloc] initWithFormat:

@"%@ button pressed.", title];

statusText.text = newText;

[newText release];

}

액션 메서드에 전달되는 인자는 이 메서드를 호출한 컨트롤 또는 객체라는 사실을 기억하자.

따라서 예제 애플리케이션에서 sender는 항상 사용자가 탭한 버튼을 가리킨다. 이는 매우 편리

한 매커니즘으로, 이를 활용하면 하나의 액션 메서드만 가지고 여러 컨트롤로부터 입력을 받아

처리할 수 있다. 이 예제에서도 이 방식을 활용한다. 두 버튼 모두 이 메서드를 호출하므로 여기

서는 sender를 통해 버튼을 구분한다. 이 메서드의 첫 번째 줄에서는 sender로부터 사용자가 탭

한 버튼의 제목을 알아온다.

NSString *title = [sender titleForState:UIControlStateNormal];

노트

이 예제에서는 버튼의 제목을 알아올 때 컨트롤의 상태를 활용한다. 컨트롤의 상태는 총 네

가지가 있다. 일반 상태는 컨트롤이 활성화돼 있지만 아직 사용되지 않은 상태를 말한다. 하

이라이트 상태는 사용자가 컨트롤을 탭하고 있거나 다른 형태로 컨트롤을 사용 중인 상태를

나타낸다. 비활성화 상태는 컨트롤이 비활성화되어 사용할 수 없는 상태를 나타낸다. 끝으

로 선택 상태는 일부 컨트롤에서만 지원하는 상태로서 컨트롤이 현재 선택됐음을 나타낸다.

UIControlStateNormal은 컨트롤의 일반 상태를 나타내며 앞으로 가장 많이 사용할 상태다.

다른 상태에 대한 값을 지정하지 않으면 일반 상태가 기본으로 적용된다.

버튼의 제목을 알아온 후에는 제목을 가지고 새로운 문자열을 생성한다.

NSString *newText = [[NSString alloc] initWithFormat:

@"%@ button pressed.", title];

새로 생성한 문자열에는 버튼 제목에 ‘button pressed’라는 텍스트를 덧붙인다. 따라서 제목이

‘Le�’인 버튼을 탭한 경우 새로운 문자열은 ‘Le� button pressed’가 된다.

이어서 라벨의 텍스트를 새로운 문자열로 설정한다.

Page 77: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 53

statusText.text = newText;

여기서는 라벨의 텍스트를 설정할 때 점 표기법을 사용하지만 이 방식 대신 [statusText

setText:newText];를 사용하더라도 결과는 같다.

끝으로 문자열을 릴리스한다.

[newText release];

객체를 사용한 후에 릴리스하는 것의 중요성은 아무리 강조해도 지나치지 않다. 아이폰, 아이

패드, 기타 iOS 기기는 리소스의 제약이 심하므로 아주 적은 양의 메모리 누수로도 프로그램이

종료될 수 있다. 이쯤에서 객체를 릴리스하지 않아도 되는 상황도 같이 설명하면 좋을 것 같다.

NSString *newText = [NSString stringWithFormat:

@"%@ button pressed.", title];

이 코드는 앞에서 사용한 코드와 똑같이 동작한다. 이 코드에 사용한 메서드 같은 클래스 메

서드는 편의(convenience) 메서드 또는 팩터리(factory) 메서드라고 부르며 자동으로 릴리스되는

객체를 반환한다. 일반적인 메모리 관리 원칙에 따르면 ‘객체에 메모리를 할당하거나 객체를 참

조 유지하지 않았다면, 객체를 릴리스하지도 않아야 한다.’ 이와 같은 자동 릴리스 객체는 명시적

으로 객체를 참조 유지하지 않는 한 릴리스하지 않아도 되며, 이들 객체를 잘 활용하면 좀 더 짧

고 읽기 쉬운 코드를 작성할 수도 있다.

하지만 이런 편의 메서드는 자동 릴리스 풀을 사용하므로 어느 정도의 부담을 감수해야 한다.

자동 릴리스 객체에 할당된 메모리는 객체를 사용한 후 일정 시간 동안 메모리에서 계속 유지된

다. 맥 OS X에서는 스왑 파일과 비교적 큰 물리 메모리로 인해 자동 릴리스 객체를 사용하는 부

담이 크지 않지만, 아이폰에서는 이들 객체가 애플리케이션의 메모리에 큰 부담을 줄 수 있다.

자동 릴리스를 사용하는 것 자체는 괜찮지만 대신 꼭 필요한 경우에만 자동 릴리스 객체를 사

용하도록 주의해야 한다. 단순히 코드 한두 줄을 줄이기 위해 자동 릴리스 객체를 사용해서는

안 된다.

다음으로 기존 viewDidUnload: 메서드에 다음 코드를 추가했다.

self.statusText = nil;

이 코드에 대해서는 지금 당장은 크게 신경쓰지 않아도 된다. 이 코드를 사용해야 하는 이유는

다음 장에서 자세히 설명할 것이다. 지금은 클래스에 들어 있는 아웃렛은 모두 viewDidUnload

에서 nil로 설정해야 한다는 정도만 알아두면 된다.

Page 78: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

54 l 시작하세요! 아이폰 4 프로그래밍

오브젝티브-C 언어의 메모리 관리 방법이 잘 이해되지 않는다면 http://developer.apple.

com/documentation/Cocoa/Conceptual/MemoryMgmt에서 메모리 관리 ‘계약’에 대한

문서를 참고하자. 아주 작은 메모리 누수도 iOS 애플리케이션에게는 큰 해가 되기 때문이다.

끝으로 dealloc 메서드에서는 아웃렛을 릴리스했다.

[statusText release];

아웃렛을 릴리스한다는 게 조금 이상해 보일 수 있을 것이다. 아웃렛 인스턴스를 생성한 적이

없는데 왜 이걸 릴리스해야 하나 의아할 것이다. 과거 버전의 코코아나 오브젝티브-C 언어를 사

용해본 적이 있다면 아마 이 코드가 명백히 잘못된 코드라는 생각이 들 수도 있다. 하지만 이들

아웃렛 각각에 대해 속성을 구현하고 속성의 어트리뷰트에서 retain을 지정했으므로 아웃렛 릴

리스는 올바른 행동일뿐더러 꼭 필요하다. 인터페이스 빌더에서는 아웃렛에 값을 대입할 때 자

동 생성된 수정자 메서드를 사용하는데, 이 수정자 메서드에서는 값을 대입받은 후 객체를 보관

하므로, 메모리 누수를 막으려면 이곳에서 아웃렛을 꼭 릴리스해야 한다.

노트

release 메서드를 사용해 statusText를 릴리스한 후에는 ([self setStatusText:nil]를 호출

할 때와는 달리) 객체가 짧은 시간 동안 무효화 상태로 남아 있는 것을 볼 수 있다. 이렇게 되

는 이유는 방금 전에 릴리스해 더 이상 존재하지 않는 객체에 대한 포인터를 statusText 변수

가 아직 갖고 있기 때문이다. 객체의 부모 클래스(또는 상속 계층 구조를 따라 그 위에 있는 상

위 클래스)가 객체의 statusText 속성에 접근하는 메서드를 호출하면 프로그램이 충돌한다.

또 다중 스레드 애플리케이션에서는 한 스레드에서 dealloc되는 객체를 다른 스레드에서 동

시에 접근하는 버그가 생길 수 있는데 이 경우에도 프로그램이 충돌하거나 실행이 멈추는 등

의 이상 행동이 일어난다. 이를 해결하려면 dealloc 메서드에서 포인터를 nil로 설정하면 되

는데, 이 방식도 잠재적인 문제점을 안고 있다. 독자들이 작성한 코드에서 방금 설명한 것과

같은 문제점이 일어난다면 (dealloc을 실행하는 중 하위 클래스에서 실수로 속성에 접근하거

나 객체 참조 관리가 제대로 되지 않는 다중 스레드 애플리케이션에서 객체를 잘못 참조한 경

우) 버그를 애플리케이션에 그냥 숨겨두지 말고 꼭 찾아서 제거해야 한다. 개발 과정에서 디버

깅을 통해 버그를 찾지 않고 dealloc 메서드에서 모든 인스턴스 변수를 그냥 nil로 설정하면

이런 버그가 잘 안 보이기 쉽다. 이 주제는 오브젝티브-C 프로그래머들 사이에서 오랫동안 열

띤 토론의 대상이 된 주제로 제프 라마시의 블로그에는 이 주제에 대한 상세한 설명이 나와 있

다(http://iphonedevelopment.blogspot.com/2010/09/dealloc.html).

Page 79: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 55

무효화된 포인터를 잘 관리해 메모리 관리 에러를 디버깅하는 것을 비롯해 이런 내용이 더 궁

금하다면 http://www.cocoadev.com/index.pl?NSZombieEnabled에서 ‘좀비 객체’에 대한 내용

도 읽어볼 것을 권장한다.

다음 과정을 진행하기 전에 파일을 먼저 저장한 후 코드 입력 과정에서 실수가 있지는 않았나

확인하기 위해 zB를 눌러 프로젝트를 빌드해 본다. 프로젝트가 컴파일되지 않는다면 다시 코드

로 돌아가 책의 예제 코드와 일치하는지 비교한다.

메시지의 중첩

어떤 개발자들은 오브젝티브-C의 메시지를 중첩해 사용한다. 독자들은 다음과 같은 코드를

간혹 본 적이 있을 것이다.

statusText.text = [NSString stringWithFormat:@”%@ button pressed.”,

[sender titleForState:UIControlStateNormal]];

이 코드 한 줄은 앞의 buttonPressed: 메서드 네 줄에서 하는 기능을 똑같이 한다. 이 책의

예제 코드에서는 코드를 명확히 하기 위해 alloc과 init을 호출하는 부분을 제외하고 이런 중

첩 메시지를 사용하지 않는다. alloc과 init의 경우 메시지를 중첩해 사용하는 방식은 오랜 관

행이며 이들 메서드에서는 거의 항상 메시지를 중첩해 사용한다.

애플리케이션 델리게이트의 활용

Button Fun 폴더에 들어 있는 또 다른 두 파일은 애플리케이션의 델리게이트를 구현한다. 코코

아 터치에서는 델리게이트를 폭넓게 활용한다. 델리게이트는 다른 객체를 대신해 특정 작업을 수

행하는 클래스를 말한다. 애플리케이션 델리게이트를 활용하면 UIApplication 클래스를 대신

해 특정 시점에 작업을 처리할 수 있다. 모든 아이폰 애플리케이션에는 UIApplication 인스턴스

가 단 하나뿐이며, 이 인스턴스는 애플리케이션의 실행 흐름을 책임지고 사용자 입력 등을 적절

한 컨트롤러 클래스로 전달하는 등의 애플리케이션 레벨 기능을 처리한다.

UIApplicat ion은 UIKit에 속하며 대부분의 작업을 내부적으로 수행하므로 보통은

UIApplication에 대해 별도로 신경 쓰지 않아도 된다. 하지만 UIApplication은 델리게이트가

있고 델리게이트에서 특정 메서드를 구현할 경우 애플리케이션이 실행되는 특정 시점에 델리게

이트의 메서드를 호출한다. 예를 들어 프로그램이 종료되기 전에 실행해야 할 코드가 있다면 애

플리케이션 델리게이트에서 applicationWillTerminate: 메서드를 구현하고 애플리케이션 종료

Page 80: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

56 l 시작하세요! 아이폰 4 프로그래밍

코드를 이 메서드 내에 작성하면 된다. 이러한 작업 위임을 통해 애플리케이션은 UIApplication

의 하위 클래스를 구현하지 않아도, 또 내부 로직을 모르더라도 애플리케이션 레벨에서 자주 사

용하는 기능을 구현할 수 있다.

그룹 & 파일 영역에서 Button_FunAppDelegate.h를 클릭하고 애플리케이션 델리게이트의 헤

더 파일을 살펴보자. 이 파일의 코드는 다음과 같을 것이다.

#import <UIKit/UIKit.h>

@class Button_FunViewController;

@interface Button_FunAppDelegate : NSObject <UIApplicationDelegate> {

UIWindow *window;

Button_FunViewController *viewController; 1

}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet Button_FunViewController

*viewController;

@end

이 파일에서는 수정할 내용이 아직 없다. 이 파일의 내용은 컨트롤러 클래스를 구현하고 나면

대부분 익숙하게 느껴질 것이다. 이 파일에서 주의해서 볼 코드는 다음 코드다.

@interface Button_FunAppDelegate : NSObject <UIApplicationDelegate> {

이 코드에서는 꺽쇠 괄호 사이에 값이 들어 있는 것을 볼 수 있다. 이 값은 이 클래스가

UIApplicationDelegate라는 프로토콜을 따르고 있음을 나타낸다. 옵션 키를 누른 상태에서 커

서를 UIApplicationDelegate 단어에 가져가보자. 그럼 커서가 십자 모양으로 바뀐다. 십자 모양

커서가 나타나면 이를 클릭한다. 그럼 그림 3-3에 보이는 것처럼 UIApplicationDelegate 프로토

콜에 대한 간략한 설명을 볼 수 있다.

1   (옮긴이) 앞서 저자들이 설명한 것처럼 이 책의 예제 코드에서는 속성을 선언할 때 항상 내부 변수를 명시적으로 선언한다. 하

지만 애플에서 템플릿으로 제공하는 코드는 이런 원칙을 따르지 않고 있다. 이 위치에 있는 변수 선언은 템플릿에서 자동 생

성한 코드가 아니라 저자들이 명시적으로 추가한 코드임을 참고하자.

Page 81: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 57

그림 3-3 | 소스 코드에서 <UIApplicationDelegate>에 대해 옵션 키를 누른 상태에서 클릭하면 Xcode가

이 팝업창을 띄워준다. 이 팝업창은 빠른 도움말 패널로서 프로토콜에 대한 설명을 보여준다.

이 문서창의 우측 상단 구석에서는 두 개의 아이콘을 볼 수 있다. 왼쪽 아이콘을 클릭하면 이

프로토콜에 대한 전체 문서를 볼 수 있고 오른쪽 아이콘을 클릭하면 헤더 파일에 들어 있는 정

의를 볼 수 있다. 이런 문서는 클래스, 프로토콜, 카테고리명 등에도 동일하게 적용되며 편집 영

역에 표시된 메서드명에서도 활용할 수 있다. 단어를 옵션 키를 누른 상태에서 더블클릭(이하 옵

션-더블클릭)하면 문서 창에서 해당 단어를 바로 찾아준다.

물론 문서 도움말을 빠르게 찾는 법을 아는 것도 중요하지만 프로토콜의 정의를 살펴보는 게

더 중요하다. 프로토콜의 정의를 살펴보면 애플리케이션의 델리게이트에서 구현할 수 있는 메서

드들을 찾아볼 수 있고 언제 해당 메서드가 호출되는지 알 수 있기 때문이다. 시간을 내서 이들

메서드에 대한 설명을 읽어두면 도움이 될 것이다.

노트

과거에 오브젝티브-C를 사용해봤지만 오브젝티브-C 2.0은 사용해본 적이 없다면 오브젝티

브-C 2.0에서는 프로토콜에서 선택 메서드를 지정할 수 있다는 사실을 참고하자. 애플리케이

션 델리게이트에서는 꼭 필요한 경우가 아니라면 이들 선택 메서드를 구현하지 않아도 된다.

프로젝트의 그룹 & 파일 영역에서 Button_FunAppDelegate.m을 클릭해 애플리케이션 델리

게이트의 구현체를 살펴보자. 이 클래스의 코드는 다음과 같을 것이다.

#import "Button_FunAppDelegate.h"

#import “Button_FunViewController.h"

@implementation Button_FunAppDelegate

@synthesize window;

Page 82: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

58 l 시작하세요! 아이폰 4 프로그래밍

@synthesize viewController;

- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 애플리케이션 구동 후 커스터마이징을 위해 오버라이드할 부분

[window addSubview:viewController.view];

[window makeKeyAndVisible];

return YES;

}

- (void)applicationWillTerminate:(UIApplication *)application {

// 필요한 경우 데이터를 저장

}

- (void)dealloc {

[window release];

[viewController release];

[super dealloc];

}

@end

이 파일의 중간 부분에서는 애플리케이션 델리게이트가 프로토콜의 메서드 중 하나인 applic

ation:didFinishLaunchingWithOptions: 메서드를 구현하는 것을 볼 수 있다. 짐작한 독자도 있

겠지만 이 메서드는 애플리케이션이 모든 설정 작업을 끝마치고 사용자와 상호작용할 준비가 됐

을 때 실행된다.

이 델리게이트의 application:didFinishLaunchingWithOptions: 메서드에서는 뷰 컨트롤러

의 뷰를 애플리케이션의 메인 창의 하위 뷰로 추가하고, 사용자가 화면 디자인을 볼 수 있게끔

창을 보이게 한다. 이런 코드는 프로젝트를 개발할 때 사용한 템플릿에서 모두 자동으로 생성해

주므로 지금 당장 여기서 할 일은 아무것도 없다.

여기서 델리게이트의 코드를 살펴본 이유는 실제로 애플리케이션의 구성 요소를 모두 조합하

기 전에 델리게이트에 대한 배경 지식을 알려주기 위한 의도였다.

Page 83: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 59

MainWindow.xib 파일의 수정

지금까지 프로젝트의 Button Fun 탭에 들어 있는 파일 네 개(두 개의 .m 파일과 두 개의 .h 파

일)를 살펴봤다. 앞 장에서는 프로젝트에 들어 있는 파일 중 두 개를 수정했다. 앞에서는 프로젝

트에 아이콘을 적용하면 Button_Fun-Info.plist와 유사한 프로퍼티 리스트 파일을 살펴봤고 또

‘Hello, World!' 라벨을 추가하면서 Button_FunViewController.xib 파일과 유사한 파일을 수정

했다.

Button Fun 탭에는 아직 설명해야 할 파일이 한 개 더 있다. 이 파일은 MainWindow.xib 파

일로서, 애플리케이션의 델리게이트, 메인 창, 뷰 컨트롤러 인스턴스가 런타임 시에 생성되게 해

준다. 이 파일은 프로젝트의 템플릿에서 제공한다. 이 장에서는 이 파일의 내용을 전혀 수정하지

않는다. 다만 여기서 이 파일에 대해 언급하는 이유는 내부적으로 어떤 작업들이 수행되는지 설

명함으로써 전체적인 그림을 독자들이 그려볼 수 있게 하기 위해서다.

그림 3-4 | 인터페이스 빌더에서 본 애플리케이션의 MainWindow.xib

Xcode의 그룹 & 파일 영역에서 Button Fun 폴더를 펼친 후 MainWindow.xib을 클릭한다. 그

럼 그림 3-4와 비슷한 화면을 편집 영역 좌측에서 볼 수 있다.

여기 있는 아이콘 중 PlaceHolders 아래 있는 두 아이콘은 2장에서 이미 살펴봤다. 복습할 겸

다시 얘기하면, Objects에 속한 나머지 아이콘은 모두 nib 파일이 로드될 때 생성할 인스턴스 객

체를 나타낸다. 이들 아이콘을 하나씩 살펴보자.

노트

Objects에 속하는 각 아이콘의 이름이 실제로 내부 객체의 클래스와 일치하지는 않음을 주의

한다. 기본 이름을 보면 보통 내부 클래스를 충분히 짐작할 수 있지만 이런 이름은 종종 바뀔

수 있다.

Page 84: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

60 l 시작하세요! 아이폰 4 프로그래밍

첫 번째 아이콘은 Button_FunAppDelegate의 인스턴스다. 두 번째 아이콘은 Button_

FunViewController의 인스턴스다. 끝으로 세 번째 아이콘은 애플리케이션의 하나뿐인 창인

UIWindow의 인스턴스다. 이들 세 아이콘은 nib 파일이 로드될 때 애플리케이션이 Button_

FunAppDelegate 애플리케이션 델리게이트 인스턴스 한 개, Button_FunViewController 뷰 컨

트롤러 인스턴스 한 개, UIWindow 인스턴스(애플리케이션의 하나뿐인 창을 나타내는 클래스)

한 개를 갖게 될 것임을 나타낸다. 이처럼 인터페이스 빌더는 인터페이스 요소를 생성하는 것 이

외에 훨씬 더 많은 일을 처리한다. 인터페이스 빌더에서는 다른 클래스의 인스턴스도 생성할 수

있는 강력한 기능도 제공한다. 작성하지 않은 코드가 많으면 많을수록 결국 디버그하거나 관리

할 부담이 있는 코드도 그만큼 줄어든다. 여기서는 코드를 한 줄도 쓰지 않고 실행 시점에 세 개

의 인스턴스를 생성하고 있다.

이로써 설명해야 할 이론은 모두 살펴봤다. 이어서 개발을 계속 진행해 보자.

Button_FunViewController.xib의 수정

이제 프로젝트를 구성하는 파일들을 하나씩 살펴봤고 이들을 한데 엮을 수 있는 개념도 충분히

익혔으므로 인터페이스를 구성하는 작업을 바로 시작해 보자.

인터페이스 빌더에서의 뷰 생성

Xcode에서 그룹 & 파일 영역에 있는 Button_FunViewController.xib을 클릭한다. 그럼 인터페

이스 빌더에서 nib 파일이 열릴 것이다. 이때 라이브러리도 함께 보이게 한다. 라이브러리가 보이

지 않으면 Views Utilities Object Library 메뉴에서 라이브러리를 선택하면 된다. 또 View 창

도 보이게 한다. View 창이 보이지 않는다면 Objects 영역에서 View 아이콘을 클릭하면 된다(그

림 3-5 참고).

이제 인터페이스를 디자인할 준비가 모두 끝났다. 이전 장에서 한 것처럼 라이브러리에서 뷰

창으로 라벨을 드래그한다. 라벨을 뷰의 하단 쪽에 배치하고 왼쪽과 하단에 있는 파란색 안내선

에 맞춰 라벨을 정렬한다(그림 3-6 참고).

Page 85: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 61

그림 3-5 | 인터페이스 빌더에서 열어본 Button_FunViewController.xib 파일

이어서 우측 면이 창의 우측 안내선과 일치하게끔 라벨의 크기를 늘린다.

그림 3-6 | 객체를 배치할 때 표시되는 파란색 안내선을 활용하는 모습

Page 86: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

62 l 시작하세요! 아이폰 4 프로그래밍

노트

파란색 안내선은 애플의 휴먼 인터페이스 가이드라인(보통 HIG라고 부른다)을 따르기 위한

것이다. 맥 OS X과 마찬가지로 애플에서는 아이폰 애플리케이션 디자인에 대한 아이폰 휴

먼 인터페이스 가이드라인을 제공한다. HIG에서는 사용자 인터페이스를 어떻게 디자인해

야 하는지 설명하고, 어떻게 디자인하지 말아야 하는지도 설명한다. HIG에는 모든 아이폰

개발자가 꼭 알아야 하는 중요한 정보가 들어 있으므로 꼭 읽어볼 것을 권장한다. HIG 문서

는 http://developer.apple.com/iphone/library/documentation/UserExperience/

Conceptual/MobileHIG/에서 확인할 수 있다.

그림 3-7 | 인스펙터의 텍스트 정렬 버튼들

라벨을 뷰의 하단에 배치한 후에는 라벨을 클릭해 선택한 후 z4 단축키를 사용해 인스펙터

를 연다. 이어서 인스펙터에 들어 있는 텍스트 정렬 버튼을 사용해 텍스트를 가운데 정렬한다(그

림 3-7 참고).

Page 87: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 63

그런 다음 라벨을 더블클릭해 기존 텍스트를 모두 지운다. 이 예제에서는 사용자가 버튼을 탭

하기 전까지는 아무 텍스트도 안 보여줄 것이다.

이어서 라이브러리에서 두 개의 Round Rect Button(그림 3-8 참고)을 드래그해 뷰에 놓는다.

그림 3-8 | 라이브러리에 있는 Round Rect Button

두 버튼을 뷰 중간쯤에 나란히 배치한다. 이때 정확한 위치는 크게 중요하지 않다. 왼쪽에 있

는 버튼을 더블클릭한다. 그럼 버튼 제목을 편집할 수 있는데 텍스트를 ‘Le�’로 변경한다. 이어서

오른쪽에 있는 버튼을 더블클릭하고 텍스트를 ‘Right’로 바꾼다. 작업을 모두 마치면 뷰가 그림

3-9와 비슷한 형태로 보일 것이다.

그림 3-9 | 작업을 완성한 최종 뷰

Page 88: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

64 l 시작하세요! 아이폰 4 프로그래밍

전체 연결

이제 인터페이스 요소는 모두 갖췄다. 남은 일은 이들 각 요소가 제대로 한데 어우러져 동작하게

끔 필요한 부분을 서로 연결하는 것뿐이다.

첫 번째로 할 일은 File’s Owner를 View 창의 라벨과 연결하는 것이다. 그런데 왜 이름이 File’s

Owner일까?

UIViewController나 UIViewController의 하위 클래스 인스턴스가 생성될 때 인스턴스는

nib 파일로부터 초기화 명령을 받는다. 예제에 사용한 템플릿에서 Button_FunViewController

클래스는 Button_FunViewController.xib이라는 nib 파일로부터 로드된다. 이때 이 부분은

프로젝트 템플릿에서 모두 처리하므로 개발자가 할 일은 아무것도 없다. 이후 장들에서는 이

런 처리 과정이 어떻게 진행되는지 자세히 보게 될 것이다. MainWindow.xib 파일은 Button_

FunViewController를 나타내는 아이콘을 갖고 있으므로 Button_FunViewController

인스턴스는 애플리케이션이 구동될 때 자동으로 생성된다. 이때 이 인스턴스가 Button_

FunViewController.xib을 메모리에 자동으로 로드하고 Button_FunViewController.xib 파일

의 소유자(File's Owner)가 된다.

이 장에서는 앞에서 nib의 소유자인 Button_FunViewController 아웃렛을 추가한 바 있다.

따라서 File’s Owner 아이콘을 사용하면 이제 아웃렛과 라벨을 서로 연결할 수 있다. 이제 이 과

정을 살펴보자.

노트

nib 로딩 절차를 전부 이해하지 못하더라도 걱정하지 않아도 된다. 이 과정은 복잡하므로 이

후 여러 장들을 통해 설명을 보태고 실제 동작 원리를 자세히 살펴볼 것이다. 지금 당장은 컨

트롤러 클래스가 같은 이름의 nib 파일에 대한 소유자라는 사실만 기억하면 된다.

아웃렛의 연결

컨트롤 키를 누른 상태에서 PlaceHolders 아래에 있는 File’s Owner 아이콘을 클릭한다. 마우스

를 누른 상태에서 File’s Owner 아이콘을 View 창으로 드래그한다. 그럼 파란색 안내선이 표시

될 것이다. 커서가 View 창의 라벨 위에 위치할 때까지 계속 드래그한다. 비록 라벨이 실제로 보

이지는 않지만 커서가 라벨 위에 올라오면 마술처럼 라벨이 다시 나타날 것이다(그림 3-10).

Page 89: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 65

그림 3-10 | 아이콘은 컨트롤-드래그해 아웃렛을 연결한다.

커서를 라벨 위에 둔 상태에서 마우스 버튼에서 손을 떼면 그림 3-11과 같은 조그만 회색 메뉴

가 표시될 것이다.

회색 메뉴에서 statusText를 선택한다.

File’s Owner를 컨트롤-드래그해 인터페이스 객체에 놓으면 인터페이스 빌더에서는 nib

파일이 로드될 때 File’s Owner의 해당 객체와 연결한다. 이 경우 File’s Owner는 Button_

FunViewController 클래스이고 Button_FunViewController에서 사용할 아웃렛은 statusText

다. File’s Owner를 드래그해 라벨 객체에 놓고 팝업 메뉴에서 statusText를 선택하면 인터페이스

빌더는 Button_FunViewController의 statusText 아웃렛이 라벨을 참조하게 함으로써 코드에

서 statusText를 사용할 때마다 이 라벨을 처리할 수 있게 해준다. 참으로 편리한 기능이 아닐 수

없다!

Page 90: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

66 l 시작하세요! 아이폰 4 프로그래밍

그림 3-11 | 아웃렛 선택 메뉴

액션의 지정

이제 남은 일은 버튼에서 호출할 액션을 지정하고 어떤 상황에서 버튼이 액션을 호출할지 알려

주는 것뿐이다. 맥 OS X용 코코아 프로그래밍에 익숙하다면 아마 버튼을 컨트롤-드래그해 File’s

Owner 아이콘에 올려놓으려고 할 것이다. 솔직히 말하자면 이렇게 하더라도 동작은 하지만 이

방식이 가장 좋은 방법은 아니다.

아이폰은 맥 OS X과 다르다. 그리고 잘 눈에 띄지 않는 이런 차이점이 분명히 드러나는 곳 중

하나가 바로 이 부분이다. 맥에서는 컨트롤이 하나의 액션하고 연계될 수 있고 보통 사용자가

컨트롤을 사용할 때 액션을 호출한다. 물론 예외도 존재하지만 전반적으로 컨트롤은 커서가 아

직 컨트롤 영역 내에 있는 상황에서 사용자가 마우스 버튼을 누를 경우 관련 액션 메서드를 호

출한다.

Page 91: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 67

그림 3-12 | 버튼에서 사용할 수 있는 이벤트들을 보여주는 커넥션 인스펙터

하지만 코코아 터치의 컨트롤은 이보다 훨씬 더 다양한 방식으로 사용할 수 있다. 따라서 컨트

롤을 클릭하고 드래그하는 대신 커넥션 인스펙터를 활용하는 법을 익히는 게 더 좋다. 커넥션 인

스펙터는 z6 단축키를 누르거나 View Utilities 메뉴에서 Connection Inspector를 선택하

면 나타난다. Le� 라벨이 들어 있는 버튼을 클릭한 상태에서 커넥션 인스펙터를 열어보자. 그럼

그림 3-12와 같은 화면이 나타날 것이다.

Events 밑에는 액션을 실행할 수 있는 전체 이벤트 목록이 나와 있다. 원한다면 다양한 이벤

트를 다양한 액션과 연결할 수도 있다. 이를테면 Touch Up Inside를 한 액션과 연결하고 Touch

Drag Inside는 또 다른 액션과 연결할 수 있다. 이 예제의 경우 연결할 내용은 아주 간단하고 쉽

다. 사용자가 버튼을 탭하면 그냥 buttonPressed: 메서드를 호출하면 되기 때문이다. 그런데 그

림 3-12에 있는 이벤트들 가운데 대체 어떤 이벤트를 사용해야 할까?

이에 대한 대답은 처음엔 다소 의아할 수도 있지만 바로 Touch Up Inside 이벤트다. 사용자가

화면에서 손가락을 뗄 때 손가락이 화면에서 완전히 떨어지기 전에 터치한 영역이 버튼 내에 속

할 경우 사용자는 Touch Up Inside 이벤트를 발생시킨다. 화면을 터치했다가 마음을 바꿀 경우

대다수 아이폰 애플리케이션에서 어떤 일이 일어나는지 생각해 보자. 버튼에서 손을 떼기 전에

는 먼저 손가락을 움직일 것이다. 애플리케이션의 사용자에게도 똑같은 동작을 할 수 있게 해줘

야 한다. 사용자의 손가락이 화면에서 떨어지는 시점에 손가락이 아직 버튼 영역 내에 있다면 사

용자가 하려는 행동이 버튼 탭임을 항상 확신할 수 있다.

Page 92: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

68 l 시작하세요! 아이폰 4 프로그래밍

이제 액션을 호출할 이벤트를 알게됐는데 이 이벤트를 특정 액션 메서드와 연결하려면 어떻게

해야 할까?

Touch Up Inside 오른쪽에 있는 작은 동그라미가 보일 것이다. 이 동그라미를 클릭하고 마우

스 버튼을 누른 상태에서 드래그한다. 이때는 컨트롤 키를 누르지 않아도 된다. 이렇게 드래그하

면 앞에서 아웃렛을 연결할 때처럼 회색 연결선이 나타날 것이다. 이 연결선을 File’s Owner 아

이콘으로 드래그하면 작은 회색 메뉴가 나타나는데, 이 메뉴에서 buttonPressed:를 선택하면 된

다. File’s Owner 아이콘은 nib 파일을 수정 중인 클래스를 나타낸다는 사실을 기억하자. 이 경

우 File’s Owner는 애플리케이션의 하나뿐인 Button_FunView Controller 클래스 인스턴스를

나타낸다. 버튼 이벤트를 File’s Owner로 드래그하면 인터페이스 빌더에서는 지정한 이벤트가 발

생할 때 해당 메서드를 호출하게 한다. 따라서 이 경우 사용자가 버튼을 터치했다가 손을 떼면

Button_FunViewController 클래스의 buttonPressed: 메서드가 호출된다.

나머지 버튼에 대해서도 동일 과정을 반복하고 파일을 저장한다. 이제 사용자가 두 버튼 중 하

나를 탭할 때마다 buttonPressed: 메서드가 호출될 것이다.

결과 확인

먼저 nib 파일을 저장한다. 이어서 애플리케이션을 실행한다. Product 메뉴에서 Run을 선택한

다. 이제 코드가 컴파일되고 애플리케이션이 아이폰 시뮬레이터에서 실행될 것이다. 이제 왼쪽

버튼을 탭하면 그림 3-1과 같이 ‘Le� button pressed.’라는 텍스트가 보이고, 오른쪽 버튼을 탭하

면 텍스트 라벨이 ‘Right button pressed.’로 바뀔 것이다.

내용 정리

이 장에서는 간단한 애플리케이션을 통해 MVC 개념을 소개하고 아웃렛과 액션을 생성해 서로

연결했으며, 뷰 컨트롤러를 구현하고 애플리케이션 델리게이트도 활용해 봤다. 이 장에서는 버

튼을 탭할 때 액션 메서드를 실행하는 법을 배웠고 런타임 시에 라벨 텍스트를 변경하는 법도 살

펴봤다. 이 장의 예제는 간단하긴 하지만 이 장에서 소개한 기본 개념들은 버튼뿐 아니라 iOS에

서 제공하는 모든 컨트롤을 활용할 때 똑같이 적용된다. 실제로 이 장에서 버튼과 라벨을 사용

한 과정은 iOS의 대다수 표준 컨트롤을 구현하고 이들 컨트롤과 상호작용할 때도 거의 똑같은

형태로 진행된다.

Page 93: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

03 기본적인 상호작용의 처리 l 69

이 장의 내용은 모두 이해해야 하며 왜 이렇게 하는지 꼭 알아야 한다. 아직 이해되지 않는 부

분이 있다면 완전히 이해할 때까지 해당 부분을 반복 숙달하자. 이런 습관을 들이는 게 중요하

다. 만일 지금 이 장의 내용을 다 이해하지 못했다면 이 책에서 앞으로 나올 좀 더 복잡한 인터페

이스를 생성할 때는 그만큼 더 어려워질 것이기 때문이다.

다음 장에서는 표준 iOS 컨트롤에 속한 컨트롤들을 몇 가지 살펴본다. 또 경고창을 활용해 사

용자에게 중요한 정보를 알려주는 법과 액션 시트를 활용해 작업을 진행하기 전에 사용자가 항

목을 선택할 수 있게 하는 법을 배운다. 다음 장을 배울 준비가 됐다면 스스로 좋은 학생임을 인

정한다는 의미로 자신의 어깨를 살짝 토닥여주고 다음 장으로 넘어가자.

Page 94: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

Beg

inni

ng iP

hone

4

Dev

elop

men

t

Page 95: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

71

04더 재미있는 사용자 상호작용

3장에서는 MVC 개념을 소개하고, 생각한 내용을 실제 애플리케이션으로 구현해 봤다. 3장에서

는 아웃렛, 액션에 대해 배웠고 이를 활용해 버튼 컨트롤과 텍스트를 서로 연계했다. 이 장에서

는 컨트롤에 대한 지식을 한 단계 더 넓힐 수 있는 애플리케이션을 개발한다.

이 장에서는 이미지 뷰, 슬라이더, 두 개의 텍스트 필드, 분할 컨트롤, 한두 개의 스위치, 그리고

진짜 iOS 버튼 같은 느낌이 나는 iOS 버튼을 구현한다. 이 장을 통해 독자들은 뷰 계층 구조를

활용해 여러 항목을 하나의 부모 뷰로 관리함으로써 런타임 시에 인터페이스를 쉽게 관리하는

법을 배운다. 이 장에서는 아웃렛과 액션 메서드의 sender 인자를 모두 활용해 다양한 컨트롤의

값을 설정하고 조회하는 법도 배운다. 이런 내용을 다룬 후에는 액션 시트를 활용해 사용자가 항

목을 선택하게 하는 법과 경고창을 통해 사용자에게 중요한 피드백 정보를 전달하는 법을 배운

다. 또 상태를 제어하는 법을 살펴보고, 확장 가능한 이미지를 활용해 버튼을 좀 더 버튼답게 꾸

미는 법도 배운다.

이 장의 애플리케이션에서는 매우 많은 사용자 인터페이스 항목들을 사용하므로 앞의 두 장

에서 한 방식과는 조금 다르게 작업을 진행한다. 즉 애플리케이션을 여러 부분으로 쪼갠 후 한

번에 한 부분만을 구현하고 다음 단계로 나아가기 전에 Xcode와 iOS 시뮬레이터를 오가면서 각

부분을 테스트하는 형태로 개발을 진행한다. 복잡한 인터페이스를 개발할 때 구현할 인터페이

스를 여러 부분으로 나누면 작업에 임하는 부담도 훨씬 줄고, 실제 애플리케이션 개발 또한 이런

방식으로 진행한다. 소프트웨어 개발자의 평범한 하루는 이와 같은 코딩-컴파일-디버깅 사이클

의 반복이 주를 이룬다.

Page 96: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

72 l 시작하세요! 아이폰 4 프로그래밍

컨트롤로 가득 찬 화면

앞에서 언급한 것처럼 이 장에서 개발할 애플리케이션은 3장에서 만든 애플리케이션보다 조금

더 복잡하다. 이 애플리케이션에서도 하나의 뷰와 컨트롤러를 사용하지만, 그림 4-1에 보이는 것

처럼 단일 뷰 내에서 진행되는 내용이 상당히 많다.

그림 4-1 | 텍스트 필드, 라벨, 슬라이드, 기타 iOS 컨트롤이 들어 있는 Control Fun 애플리케이션.

그림 4-2 | 왼쪽에 있는 분할 컨트롤을 탭하면 스위치가 두 개 나타난다. 오른쪽 분할 컨트롤을 탭하면 버튼

이 표시된다.

Page 97: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 73

아이폰 화면 상단에 있는 로고는 이미지 뷰로서, 애플리케이션에서는 정적 이미지를 보여주는

것 외에 아무런 일도 하지 않는다. 로고 아래에는 두 개의 텍스트 필드가 들어 있다. 이 중 하나는

알파벳과 숫자 텍스트를 보여주고 다른 하나는 숫자 텍스트만 보여준다. 텍스트 필드 아래에는

슬라이더가 있다. 사용자가 슬라이더를 움직이면 슬라이더 옆에 있는 라벨값이 슬라이더 값에

맞춰 바뀐다.

슬라이더 아래에는 분할 컨트롤과 두 개의 스위치가 있다. 분할 컨트롤은 자신의 아래 영역에

있는 두 타입의 컨트롤 사이에서 토글된다. 애플리케이션이 처음 실행되면 두 개의 스위치가 분

할 컨트롤 아래에 보인다. 두 스위치 중 하나의 값을 바꾸면 이에 따라 다른 스위치의 값도 바뀐

다. 물론 실제 애플리케이션이라면 이런 식의 연동 방식을 사용하지 않겠지만, 여기서는 이런 방

식을 통해 프로그래밍적으로 컨트롤의 값을 변경하는 법을 살펴보고, 코코아 터치에서 추가 작

업 없이 특정 행동에 애니메이션을 적용하는 법을 배울 것이다.

그림 4-2에는 사용자가 분할 컨트롤을 탭할 때 수행되는 결과가 나와 있다. 분할 컨트롤을 탭

하면 스위치가 사라지고 그 자리를 버튼이 대신 차지한다. Do Something 버튼을 누르면 액션 시

트가 팝업되고 사용자가 버튼을 탭하려고 하는지 묻는다(그림 4-3 참고). 액션 시트는 잠재적인

위험 요소가 있거나 큰 파급 효과가 있는 사용자 입력에 반응하는 표준 방식으로서, 사용자들에

게 부정적인 결과가 될 수도 있는 행동을 미연에 방지할 수 있게 해준다. 액션 시트에서 사용자가

Yes, I’m Sure!를 선택하면 애플리케이션은 모든 것이 정상 처리됐음을 알리는 경고창을 띄운다

(그림 4-4).

그림 4-3 | 예제 애플리케이션에서는 액션 시트를 활용해 사용자로부터 반응을 이끌어낸다.

Page 98: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

74 l 시작하세요! 아이폰 4 프로그래밍

그림 4-4 | 경고창은 중요한 일이 일어났음을 사용자에게 알려주는 용도로 사용한다. 이 장의 예제에서는

모든 상황이 정상적으로 진행됐음을 알려주는 경고창을 하나 사용한다.

능동적 컨트롤과 수동적 컨트롤

사용자 인터페이스 컨트롤은 능동적 컨트롤과 수동적 컨트롤의 두 종류로 크게 나뉜다. 이전 장

에서 사용한 버튼들은 능동적 컨트롤의 대표적인 예이다. 이런 버튼을 누르면 코드가 실행되는

등의 동작이 일어난다.

어떤 컨트롤은 사용하기 전까지 사용자가 입력한 값을 단순히 보관만 하는 수동적인 형태로

동작한다. 이런 컨트롤은 액션 메서드를 호출하지 않지만 사용자는 이들 컨트롤과 상호작용해

값을 얼마든지 바꿀 수 있다. 수동적인 컨트롤의 대표적인 예로는 웹 페이지의 텍스트 필드가 있

다. 물론 입력 필드를 벗어날 때 유효성 검증 코드 등이 실행될 수도 있지만, 웹 페이지에 있는 텍

스트 필드 중 상당수는 전송 버튼을 클릭할 때 서버로 전송할 데이터 값을 보관하는 용도로만

사용한다. 이런 텍스트 필드는 그 자체로는 아무런 코드도 실행하지 않지만, 사용자가 전송 버튼

을 클릭하면 텍스트 필드의 데이터가 서버로 전송된다.

iOS 기기에서 대다수 컨트롤은 사용자의 필요에 따라 두 방식으로 모두 사용할 수 있다. 모든

iOS 컨트롤은 UIControl의 하위 클래스이므로 액션 메서드를 실행할 수 있다. 또 대다수 컨트

롤은 수동적으로 사용할 수 있다. 하지만 버튼 같은 일부 컨트롤은 능동적으로 코드를 실행하는

것 이외의 다른 방식으로 사용하면 본래 사용 목적에 잘 부합하지 않는다.

Page 99: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 75

예상한 독자들도 있겠지만 iOS의 컨트롤과 맥의 컨트롤 사이에는 동작상의 차이점이 존재한

다. 몇 가지 예를 들면 다음과 같다.

▶ 멀티 터치 인터페이스로 인해 모든 iOS 컨트롤은 터치 방식에 따라 여러 액션을 호출할

수 있다. 사용자는 단순 터치가 아니라 스와이프 제스처를 통해 다른 액션 메서드가 실행

되게 할 수도 있다.

▶ 사용자가 버튼을 누를 때는 한 액션이 실행되게 하고 사용자가 버튼에서 손을 뗄 때는 다

른 액션이 실행되게 할 수 있다.

▶ 한 컨트롤이 단일 이벤트를 통해 여러 액션 메서드를 호출하게 할 수 있다. 예를 들어 ‘터

치 업 인사이드’ 이벤트에서 두 개의 각기 다른 액션 메서드가 호출되게 할 수 있다. 이 말

은 사용자의 손가락이 버튼을 터치한 후 화면에서 떨어질 때 두 메서드를 함께 실행할 수

있다는 뜻이다.

노트

한 컨트롤에서 여러 액션 메서드를 호출하는 것은 MVC 아키텍처에서 조금 벗어나는 것이므

로 이 경우 특정 버튼을 누를 때 필요한 작업을 모두 처리하는 단일 액션 메서드를 구현하는

게 더 바람직하다. 인터페이스 빌더를 사용해 작업할 때는 액션과 이벤트를 연결한다고 해서

이전에 연결된 액션과 이벤트가 끊어지는 게 아님을 꼭 명심해야 한다. 이를 잘못 이해하면 애

플리케이션이 이상한 동작을 할 수 있으므로 인터페이스 빌더에서 이벤트를 재설정할 때는 눈

을 크게 뜨고 주의해서 작업을 진행해야 한다.

iOS와 맥의 또 다른 주된 차이점은 iOS 기기에는 보통 물리적인 키보드가 없다는 것이다(물

론 외부 키보드를 연결하지 않았을 경우를 말한다). 표준 iOS 키보드는 실제로는 버튼 컨트롤을

나란히 배열한 뷰에 지나지 않는다. 물론 코드에서 직접 iOS 키보드와 상호작용할 일은 없겠지

만, 이 장에서 나중에 보는 것처럼 때로는 의도한 대로 키보드가 동작하게 하는 코드를 작성해

야 한다.

애플리케이션의 생성

아직 열려 있지 않다면 Xcode를 실행하고 Control Fun이라는 새로운 프로젝트를 생성하자. 이

프로젝트에서도 View-based Application 템플릿을 사용할 것이므로 앞의 두 장에서 한 것처럼

프로젝트를 생성하면 된다.

Page 100: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

76 l 시작하세요! 아이폰 4 프로그래밍

프로젝트를 생성한 후에는 애플리케이션의 이미지 뷰에서 사용할 이미지를 가져와야 한다. 이

이미지는 인터페이스 빌더 내부에서 사용하기 전에 먼저 Xcode로 임포트해야 하므로 바로 임포

트한다. 04 Control Fun 폴더의 프로젝트 압축 파일에서 필요한 .png 파일을 찾아 사용해도 되

고, 독자들이 선택한 이미지를 사용해도 된다. 직접 선택한 이미지를 사용할 경우에는 사용할 수

있는 공간에 맞게 크기를 조절한 .png 이미지를 사용한다. 이미지 크기는 리사이즈하지 않아도

뷰의 상단에 배치할 수 있게 세로가 100픽셀보다 작아야 하고 가로 길이는 최대 300픽셀을 넘지

않아야 한다.

2장에서 한 것처럼 Finder에서 이미지를 드래그해 프로젝트의 Supporting Files 폴더에 이미

지를 추가한다.

이미지 뷰와 텍스트 필드의 구현

프로젝트에 이미지를 추가한 다음에는 애플리케이션 화면 상단에 다섯 개의 인터페이스 요소

를 구현해야 한다. 구현할 UI 요소는 이미지 뷰, 두 개의 텍스트 필드, 두 개의 라벨이다(그림

4-5 참고).

그림 4-5 | 이미지 뷰, 라벨, 텍스트 필드를 먼저 구현한다.

아웃렛에 대한 판단

GUI 개발을 시작하기 전에 먼저 이들 객체 중 아웃렛이 필요한 객체가 어떤 객체인지 판단해야

한다. 이때 nib 편집기에서 연결을 수행하기 전에 아웃렛을 컨트롤러 클래스의 헤더 파일에 먼저

정의해야 한다는 사실을 기억해야 한다.

이 예제에서 이미지 뷰는 정적인 이미지만을 보여준다. 이미지 뷰에서 보여줄 이미지는 인터페

이스 빌더에서 바로 지정할 것이고, 이 이미지는 애플리케이션이 실행되는 도중에 변하지 않는

Page 101: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 77

다. 따라서 이미지 뷰는 아웃렛이 필요 없다. 만일 런타임 시에 이미지를 바꿀 생각이거나 이미지

의 속성을 하나라도 바꿀 생각이 있다면 당연히 아웃렛이 필요하다. 하지만 이 예제의 이미지 뷰

는 이런 해당 사항이 전혀 없다.

두 개의 라벨도 마찬가지다. 이들 라벨은 텍스트를 보여주는 용도로 사용하지만 런타임 시에 아

무것도 내용이 바뀌지 않으며 사용자와의 상호작용도 없다. 따라서 라벨도 아웃렛이 필요 없다.

그에 반해 두 텍스트 필드는 안에 들어 있는 데이터를 활용할 수 없다면 별 쓸모가 없다. 수동

적인 컨트롤에서 보관하는 데이터에 접근하려면 아웃렛을 사용해야 하므로 이들 텍스트 필드에

대해서는 아웃렛을 정의해야 한다. 지금쯤이면 아웃렛 정의는 이미 익숙할 것이므로 Control_

FunViewController.h 클래스 파일에 nameField와 numberField라는 이름으로 아웃렛을 두 개

정의하자. 작업이 끝나면 Control_FunViewController.h의 내용은 다음과 같이 될 것이다.

#import <UIKit/UIKit.h>

@interface Control_FunViewController : UIViewController {

UITextField *nameField;

UITextField *numberField;

}

@property (nonatomic, retain) IBOutlet UITextField *nameField;

@property (nonatomic, retain) IBOutlet UITextField *numberField;

@end

이어서 nib 파일에 대한 작업을 하기 전에 @synthesize 지시어를 Control_FunViewController.m

에 추가한다.

#import "Control_FunViewController.h"

@implementation Control_FunViewController

@synthesize nameField;

@synthesize numberField;

...

노트

이 코드 예제에서는 끝에 말줄임표(...)를 사용했다. 이 기호는 예제에 보이는 코드 다음에 나

오는 기존 코드를 생략하는 기호로 사용한다. 이 장에서는 매번 새로운 코드를 추가할 때마다

전체 파일을 반복해서 수록하지 않도록 모든 코드를 구현체 파일의 상단부에 추가하고 말줄임

표를 사용해 나머지 코드를 생략한다.

Page 102: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

78 l 시작하세요! 아이폰 4 프로그래밍

아웃렛을 구현할 때는 메모리에 대해서도 주의해야 한다. 앞에서 retain 키워드를 사용해

nameField와 numberField 속성을 선언했으므로 dealloc 메서드에서는 둘 다 릴리스해야 한다.

파일의 하단 부분까지 스크롤 한 후 기존 dealloc 메서드에 다음 코드 두 줄을 추가한다.

- (void)dealloc {

[nameField release];

[numberField release];

[super dealloc];

}

액션에 대한 판단

그림 4-5에 있는 다섯 개의 객체(이미지 뷰, 두 개의 텍스트 필드, 두 개의 라벨)를 다시 한 번 살

펴보자. 이 중 액션을 선언해야 할 객체가 있을까? 이 애플리케이션에서는 사용자가 라벨이나

이미지 뷰와 상호작용할 수 없으므로 이들 컨트롤에 대해서는 액션을 생성하지 않아도 된다.

그럼 두 텍스트 필드는 어떨까? 텍스트 필드는 수동적인 컨트롤의 전형적인 예다. 대부분의

경우 텍스트 필드가 하는 일은 값을 사용할 때까지 정보를 보관하는 게 전부다. 예제 애플리케

이션에서는 전체 키보드 대신 숫자 패드만 보여줌으로써 숫자 필드의 입력을 제한하는 것 이외

에(이 부분은 인터페이스 빌더에서 모두 처리할 수 있다) 이런 텍스트 필드에 대해 유효성 검증

을 수행하지도 않으므로 이들 텍스트 필드도 액션이 필요 없다. 과연 그럴까? 이런 생각을 그대

로 유지한 채 첫 번째로 개발한 사용자 인터페이스 부분을 빌드하고 테스트하자.

인터페이스의 개발

두 파일을 저장했는지 확인한 후 그룹 & 파일 영역에서 Control Fun 폴더를 펼치고 Control_

FunViewController.xib을 클릭해 편집한다. 이때 View라는 제목의 창이 보이지 않는다면

Objects 영역에서 View 아이콘을 클릭하면 된다.

이어서 라이브러리를 살펴본다. 라이브러리 목록을 1/4쯤 내려오면 Image View를 찾을 수 있

다(그림 4-6 참고).

Page 103: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 79

그림 4-6 | 인터페이스 빌더의 라이브러리에 들어 있는 Image View 요소

이미지 뷰의 추가

이미지 뷰를 View 창으로 드래그한다. 뷰에 UI 요소를 추가하는 게 이번이 처음이므로 인터페

이스 빌더에서는 자동으로 이미지 뷰의 크기가 뷰의 전체 크기와 같게 조절해줄 것이다. 이 예제

에서는 이미지 뷰가 전체 공간을 모두 차지하면 안 되므로 핸들을 드래그해 이미지 뷰의 크기를

Xcode에 임포트한 이미지 크기와 비슷하게 맞춘다. 이때 이미지 크기를 정확히 맞추지 못하더라

도 걱정하지 않아도 된다. 잠시 후 더 쉬운 방법을 보게 될 것이다.

때로는 객체가 다른 객체 뒤로 가거나, 전체 뷰를 차지하거나, 보더가 없어서 한 번 선택 해제한

후 다시 선택하기가 매우 까다로운 경우가 있다. 이때도 짜증낼 필요가 없다. 다시 손쉽게 객체를

선택할 수 있는 방법이 있기 때문이다. Objects 영역을 보면 그림 4-7에 나온 것처럼 하위 뷰로 얼

마든지 내려 갈 수 있다. 이 뷰에서 아무 항목이나 클릭하면 해당 항목과 동일한 항목을 View 창

에서 선택할 수 있다.

그림 4-7 | Objects 영역에서 하위 뷰를 선택하는 화면

Page 104: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

80 l 시작하세요! 아이폰 4 프로그래밍

그림 4-8 | 이미지 뷰의 어트리뷰트 인스펙터

이미지 뷰를 선택한 상태에서 z4 단축키를 통해 인스펙터를 열면 그림 4-8과 같이

UIImageView 클래스에서 수정할 수 있는 옵션들을 볼 수 있다.

예제 애플리케이션의 이미지 뷰에서 가장 중요한 설정은 인스펙터의 최상단에 있는 항목인

Image다. 이 항목의 오른쪽 필드에서 작은 화살표를 클릭하면 사용할 수 있는 이미지 목록이 팝

업 형태로 뜨는데, 이 중에는 앞서 Xcode 프로젝트에 포함시킨 이미지도 들어 있을 것이다. 이제

방금 전에 추가한 이미지를 선택하면 이미지 뷰에서 이미지를 바로 볼 수 있다.

이미지 뷰의 크기 조절

이제 이미지 크기에 맞춰서 이미지 뷰의 크기를 조절해야 한다. 이미지 크기를 조절해야 하는 이

유는 잠시 후 알게 될 것이다. 선택한 이미지에 맞게 이미지 뷰의 크기를 쉽게 조절하려면 z=를

누르거나 Editor 메뉴에서 Size to Fit을 선택하면 된다. 그럼 자동으로 내용에 맞게 뷰의 크기가

정확히 조절된다. 이미지 크기를 조절한 후에는 보기 좋게 이미지를 화면 중앙에 배치하고 파란

색 안내선을 따라 상단 위치를 맞추는 게 좋다. Editor 메뉴의 Alignment 하위 메뉴에서 Align

Horizontal Center in Container를 선택하면 뷰의 항목을 쉽게 가운데 정렬할 수 있다.

Page 105: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 81

인터페이스 빌더에서 뷰를 드래그하고 크기를 조절하는 작업은 꽤 까다로울 수 있다. 이때는

Objects 영역의 계층적인 뷰를 활용한다. 이렇게 하면 이미지 뷰를 쉽게 찾아서 선택(클릭)

할 수 있다. 크기를 변경하려면 옵션 키를 누르고 인터페이스 빌더에서 보여주는 빨간색 안내

선을 사용해 크기를 가늠하면 된다. 드래그를 할 때는 이 방식을 사용할 수 없지만 Editor 메

뉴에서 Show Bounds Rectangles를 선택하면 인터페이스 항목 주변에 선이 그어지므로 각

항목을 쉽게 구분할 수 있다. 이런 구분선을 제거하려면 Show Bounds Rectangles를 한 번

더 선택하면 된다.

모드 어트리뷰트

이미지 뷰 인스펙터에서 다음으로 사용할 옵션은 Mode라는 이름의 팝업 메뉴다. Mode 메뉴는

뷰 내에서 이미지가 정렬되는 방법을 정의하고 크기에 맞게 스케일을 조정할지 여부를 지정한다.

이 어트리뷰트 값으로는 다양한 옵션을 원하는 대로 적용해도 괜찮지만 예제의 본래 의도에 가

장 적합한 설정은 Center 값이다. 이때 이 옵션 이외에 다른 옵션을 선택하면 프로세스 부담이

가중될 수 있다는 점을 감안해야 한다. 따라서 이런 옵션은 가능한 한 피하는 게 좋고 이미지를

임포트하기 전에는 먼저 이미지를 올바른 크기로 수정해야 한다. 같은 이미지를 여러 크기로 보

여주고 싶다면 다양한 크기의 이미지를 여러 개 사용하는 게 iOS 기기에서 런타임 시에 이미지

스케일을 조절하는 것보다 더 좋다.

알파 슬라이더

인스펙터에서 다음으로 볼 항목은 알파인데, 이 항목은 매우 주의해서 사용해야 한다. 알파는

이미지의 투명도를 정의한다. 즉 이미지 아래 영역을 얼마만큼 보여줄지 지정하는 것이다. 이 값

을 1.0 미만으로 지정하면 아이폰에서는 아래 있는 객체들이 투영돼 보이게끔 해당 뷰를 투명하

게 그린다. 알파 값이 1.0 미만인 경우에는 이미지 아래에 실제로 아무 객체도 없더라도 애플리케

이션에서는 투명도를 계산하는 프로세스 주기가 계속 실행하므로, 특별히 알파 값을 꼭 지정해

야 하는 경우가 아니라면 이 값은 항상 1.0으로 설정하는 게 좋다.

배경 옵션의 무시

아래 있는 항목인 Background는 무시해도 상관없다. 이 어트리뷰트는 UIView에서 상속한 속

성으로서 이미지 뷰의 외양에 아무런 영향도 주지 않는다.

Page 106: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

82 l 시작하세요! 아이폰 4 프로그래밍

태그 어트리뷰트

다음으로 살펴볼 항목은 태그인데 이 장에서는 태그 어트리뷰트를 사용하지는 않지만 중요하므

로 함께 설명하겠다. 뷰와 컨트롤을 비롯해 모든 UIView의 하위 클래스는 tag라는 속성을 갖고

있다. 태그는 실제로는 숫자 값으로, 이미지를 따라 다니는 꼬리표다. 태그는 개발자를 위한 용도

로 설계된 속성이다. 시스템에서는 이 값을 설정하거나 바꾸지 않는다. 컨트롤이나 뷰에 태그 값

을 지정하면 직접 바꾸지 않는 한 이 값은 항상 지정한 값을 그대로 유지한다.

태그를 활용하면 언어와 상관없이 인터페이스 객체를 쉽게 판별할 수 있다. 예를 들어 각기 다

른 라벨이 들어 있는 다섯 개의 버튼이 있고 하나의 액션 메서드를 사용해 다섯 개 버튼을 모두

처리한다고 가정하자. 이 경우 액션 메서드가 호출될 때 버튼을 서로 구분할 수 있어야 한다. 물

론 버튼의 제목을 살펴봐도 괜찮지만 애플리케이션의 내용이 스와힐리어나 산스크리트어로 번

역된다면, 로직이 제대로 동작하지 않을 수 있다. 라벨과 달리 태그는 절대 바뀌지 않으므로 인터

페이스 빌더에서 태그를 일단 설정하면 액션 메서드에 전달된 sender 인자를 활용해 쉽고 안전하

게 컨트롤을 서로 구분할 수 있다.

드로잉 체크박스

태그 아래에는 여러 개의 드로잉 체크박스가 보인다. 첫 번째 체크박스의 라벨은 Opaque이다.

이 체크박스는 항상 체크한다. 이 체크박스를 체크하면 iOS에서는 뷰 아래에서 아무것도 그리지

않으므로 iOS의 드로잉 메서드를 최적화해 드로잉 속도를 개선할 수 있다.

독자들 중에는 앞에서 이미 Alpha 값을 1.0으로 설정해 불투명도를 지정했는데 왜 또 다시

Opaque 체크박스를 체크해야 하는지 궁금한 사람도 있을 것이다. 그 이유는 알파 값 자체는 드

로잉되는 이미지 영역에 적용되는데 이미지가 이미지 뷰를 모두 채우지 못하거나 알파 채널 또는

클립 패스에 따라 이미지에 구멍이 있는 경우 Alpha 값과 상관없이 아래 있는 객체가 보일 수 있

기 때문이다. 하지만 Opaque을 설정하면 iOS에서는 어떤 경우에도 이 뷰 아래에 있는 항목들은

드로잉할 필요가 없음을 알게 되므로 객체 아래에 있는 내용을 그리느라 프로세스를 낭비하지

않게 된다. 여기서는 앞에서 이미 Size to Fit을 설정해 이미지 뷰의 크기를 이미지에 맞췄으므로

안심하고 Opaque 체크박스를 선택해도 된다.

Hidden 체크박스는 독자들이 체크박스 이름에서 짐작한 기능을 그대로 수행한다. 이 체크박

스를 선택하면 사용자는 컨트롤을 볼 수 없다. 이 장에서 나중에 스위치와 버튼을 감출 때처럼

경우에 따라서는 컨트롤을 감추는 게 도움이 되기도 하지만 대부분의 경우에는 이 체크박스를

선택 해제한 상태로 사용하는 게 좋다. 여기서는 기본값을 그대로 사용한다.

Page 107: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 83

다음으로 나와 있는 체크박스는 Clear Context Before Drawing 체크박스인데, 이 체크박스는

거의 선택할 일이 없다. 이 체크박스를 선택하면 iOS에서는 실제로 컨트롤을 그리기 전에 컨트롤

이 덮고 있는 전체 영역을 투명한 검은색으로 그린다. 이 체크박스는 거의 사용하지 않고 성능 문

제도 있으므로 기본적으로 선택돼 있지 않다. 이 체크박스도 항상 선택 해제된 상태로 둔다.

Clip Subviews는 재미있는 옵션이다. 뷰에 하위 뷰가 있고 이들 하위 뷰가 부모 뷰의 영역

내에 완전히 속하지 않는 경우 이 체크박스에서는 하위 뷰를 드로잉할 방법을 판단한다. Clip

Subviews를 선택하면 부모 뷰 영역에 속한 하위 뷰 영역만 그려진다. Clip Subviews를 선택 해제

하면 하위 뷰가 부모 뷰 영역을 벗어나더라도 하위 뷰를 완전히 그린다.

이 체크박스의 기본값을 보면 얼핏 정반대로 지정되는 게 맞지 않나 하는 생각이 들 수 있다.

즉 Clip Subviews가 기본으로 활성화돼 있는 게 맞지 않나 하는 생각이 들 것이다. 하지만 이런

기본값을 사용하지 않는 이유는 아이폰의 다른 기본값과 마찬가지로 성능과 관련이 있다. 잘라

낼 영역을 계산하고 하위 뷰의 일부 영역만을 보여주려면 많은 연산을 해야 하며, 통계적으로 보

더라도 대부분의 경우 하위 뷰가 상위 뷰 영역을 벗어나는 경우는 많지 않다. 물론 그럴 만한 이

유가 있다면 Clip Subviews 체크박스를 활성화해도 되지만 이 체크박스도 성능 문제로 인해 기

본적으로 비활성화돼 있다.

이 절에서 마지막으로 볼 체크박스는 Autoresize Subviews로서 뷰의 크기가 바뀔 때 iOS가 하

위 뷰의 크기를 변경하게 해주는 체크박스다. 이 체크박스는 선택 해제된 상태로 그냥 둔다. 예제

애플리케이션의 경우 뷰의 크기를 변경할 수 없으므로 이 설정을 사용한다고 해도 아무런 도움

이 안 된다.

인터랙션 체크박스

마지막에 있는 두 개의 체크박스는 사용자 상호작용과 관련된다. 첫 번째 체크박스인 User

Interaction Enabled는 사용자가 객체를 가지고 뭔가를 할 수 있는지 여부를 지정한다. 이 체크

박스는 대부분의 컨트롤에서 기본으로 선택돼 있다. 이 체크박스가 선택돼 있지 않으면 컨트롤

에서 액션 메서드를 전혀 실행할 수 없기 때문이다. 하지만 라벨과 이미지 뷰에서는 거의 대부분

정적인 정보만을 보여주므로 이 체크박스가 기본으로 선택 해제돼 있다. 이 화면에서 하는 일도

그림을 보여주는 것뿐이므로 여기서는 이 체크박스를 선택하지 않아도 된다.

두 번째 체크박스는 Multiple Touch로서 컨트롤에서 멀티터치 이벤트를 받을 수 있는지 여부

를 지정한다. 멀티터치 이벤트는 많은 iOS 애플리케이션에서 핀치 같은 복잡한 제스처를 사용해

줌 기능 등을 사용할 수 있게 해 준다. 제스처와 멀티터치 이벤트는 15장에서 자세히 설명할 것

Page 108: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

84 l 시작하세요! 아이폰 4 프로그래밍

이다. 이 이미지 뷰에서는 사용자와 상호작용할 내용이 전혀 없고 멀티터치 이벤트를 사용할 필

요도 없으므로 이 체크박스 또한 선택 해제한 채로 둔다.

텍스트 필드의 추가

이미지 뷰에 대한 작업을 모두 마치면 라이브러리에서 텍스트 필드를 선택해 View 창으로 드래

그한다. 텍스트 필드를 이미지 뷰 아래 놓고 파란색 안내선을 따라 오른쪽 마진을 맞춘다(그림

4-9 참고). 텍스트 필드를 이미지 뷰 하단으로 아주 가까이 움직이면 텍스트 필드 위에 파란색 가

로 안내선이 표시될 것이다. 이 안내선은 다른 객체에 최대한 가까이 다가갔음을 알려주는 안내

선이다. 지금은 텍스트 필드를 그냥 이곳에 두어도 되지만 전체적인 디자인 균형을 맞추려면 텍

스트 필드를 이보다 조금 아래로 움직이는 게 더 좋다. 인터페이스 요소의 위치를 조절하거나 크

기를 변경할 때는 코드를 수정하거나 연결을 재설정할 필요 없이 항상 인터페이스 빌더로 돌아

와 크기 및 위치를 변경할 수 있다는 사실을 기억하자.

그림 4-9 | 텍스트 필드의 배치. 이 그림에서 텍스트 필드 위에 있는 파란색 안내선은 텍스트 필드를 더 이

상 이미지 가까이로 움직이지 말라는 안내선이다.

텍스트 필드를 드롭한 후에는 라이브러리에서 라벨을 드래그해 뷰의 왼쪽 마진에 맞춰 정렬하

고 앞서 배치한 텍스트 필드와 수직 위치를 맞춰 정렬한다. 이 경우 라벨을 움직이는 도중 여러

개의 파란색 안내선이 나와 상단, 하단, 중간, 또는 텍스트의 기준선을 사용해 라벨을 텍스트 필

드에 맞게 정렬하도록 도와줄 것이다. 라벨과 텍스트 필드는 텍스트의 기준선에 따라 정렬한다.

Page 109: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 85

이렇게 하면 그림 4-10과 같이 라벨의 Label 텍스트 하단에서 텍스트 필드까지 선이 하나 그어질

것이다. 이때 선이 Label 텍스트의 중심을 통과한다면 텍스트 기준선이 아니라 중앙 기준선을 따

라 정렬한 것이다. 텍스트 기준선을 활용해 라벨과 텍스트를 정렬하면 라벨의 텍스트와 사용자

가 입력할 텍스트가 화면상에서 같은 수직선상에 위치하게 된다.

그림 4-10 | 텍스트 기준선을 활용한 라벨과 텍스트 필드의 정렬

그림 4-11 | 두 번째 텍스트 필드 추가하기

Page 110: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

86 l 시작하세요! 아이폰 4 프로그래밍

방금 드롭한 라벨을 더블클릭하고 내용을 Label 대신 Name:으로 변경한 후 리턴 키를 눌러서

수정한 내용을 반영한다. 이어서 또 다른 텍스트 필드를 라이브러리에서 뷰로 드래그하고 안내

선을 활용해 첫 번째 텍스트 필드 아래에 배치한다(그림 4-11 참고).

두 번째 텍스트 필드까지 잘 배치했다면 라이브러리에서 또 다른 라벨을 드래그해 왼쪽에 있

는 기존 라벨 아래에 배치한다. 이때도 파란색 안내선을 활용해 두 번째 텍스트 필드에 맞게 정

렬한다. 새로 추가한 라벨을 더블클릭하고 내용을 Number:로 바꾼다.

이어서 하단 텍스트 필드의 크기를 왼쪽으로 늘린다. 하단 텍스트 필드를 한 번만 클릭한 상태

에서 파란색 안내선이 나타나 라벨에 최대로 근접했음을 표시할 때까지 왼쪽 리사이즈 점을 드

래그한다(그림 4-12 참고).

그림 4-12 | 하단 텍스트 필드의 크기 늘리기

이번에는 똑같은 방식으로 상단 텍스트 필드를 하단 텍스트 필드의 크기에 맞춰 늘린다. 이때

하단 텍스트 필드부터 크기를 늘린 이유는 하단에 있는 라벨이 상단 라벨보다 더 길므로 하단

라벨을 기준으로 크기를 맞춰야 하기 때문이다.

이제 한 가지만 제외하고 텍스트 필드에 대한 기본 작업은 거의 끝났다. 그림 4-5를 다시 보자.

Name:과 Number:가 우측 정렬된 것이 보일 것이다. 하지만 현재 추가된 라벨은 왼쪽 마진을 기

준으로 정렬돼 있다. 두 라벨을 우측 정렬하려면 Name: 라벨을 클릭하고 Shift 키를 누른 상태에

서 Number: 라벨을 클릭해 두 라벨을 모두 선택해야 한다. 그런 다음 Layout 메뉴의 Alignment

하위 메뉴에서 Align Right Edges를 선택하면 된다.

Page 111: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 87

작업을 모두 마치면 76쪽 그림 4-5에서 본 것과 거의 비슷한 인터페이스를 완성할 수 있을 것

이다. 유일하게 다른 점은 각 텍스트 필드의 텍스트 색상이 옅은 회색이라는 점밖에는 없다. 이제

이 부분을 바로 추가해 보겠다.

컨트롤이 없는 화면 공간을 클릭해 두 라벨을 모두 선택 해제한 후 상단 텍스트 필드를 선택하

고 z4를 눌러서 인스펙터를 연다(그림 4-13 참고).

그림 4-13 | 텍스트 필드의 기본값을 보여주는 인스펙터 창

텍스트 필드 인스펙터 설정

텍스트 필드는 iOS에서 가장 자주 사용하는 컨트롤이면서 동시에 가장 복잡한 컨트롤 중 하나

다. 먼저 인스펙터의 최상단 영역부터 살펴보자. 첫 번째 필드인 Text에서는 이 필드에 대한 기본

값을 설정할 수 있다. 이 필드에 입력하는 값은 애플리케이션이 실행될 때 항상 텍스트 필드에 나

타난다.

두 번째 필드인 Placeholder는 텍스트 필드에 값이 없을 때 텍스트 필드 내에서 회색으로 표시

할 텍스트를 지정하는 필드다. Placeholder는 공간이 딱 맞는 경우 라벨 대신 사용하거나 텍스트

필드에 사용자가 입력해야 하는 값을 명확히 알려주는 용도로 사용할 수 있다.

Page 112: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

88 l 시작하세요! 아이폰 4 프로그래밍

이 텍스트 필드의 Placeholder에 Type in a name이란 텍스트를 입력한다.

다음 두 필드는 텍스트 필드의 외양을 커스터마이징해야 할 때만 사용한다. 하지만 텍스트 필

드의 외양에 대한 커스터마이징은 대부분의 경우 득보다 실이 많다. 사용자들은 텍스트 필드가

어떤 형태로 보일 것이라는 나름의 기대가 있다. 따라서 Background와 Disabled에 해당하는 두

필드는 빈 채로 두고 그냥 넘어간다.

이들 필드 아래에는 텍스트 필드에 표시될 텍스트 정렬 방식을 지정하는 세 개의 버튼이 있다.

이 필드에서는 기본값인 왼쪽 정렬(가장 왼쪽 버튼)을 그대로 사용한다.

다음으로 Border라는 항목에서 네 개의 버튼을 볼 수 있다. 이들 버튼은 텍스트 필드의 모서

리를 그리는 방식을 바꿀 수 있게 해준다. 네 가지 스타일은 원하는 대로 적용해도 되지만 가장

우측에 있는 버튼인 기본값을 적용할 때 iOS 애플리케이션의 사용자가 가장 편안하게 느끼는 일

반적인 텍스트 필드를 보여줄 수 있으므로, 여러 가지 스타일을 확인해 본 후에는 기본값을 다시

설정한다.

Clear When Editing Begins 체크박스는 사용자가 텍스트 필드를 터치할 때 일어날 일을 지정

한다. 이 체크박스를 선택하면 텍스트 필드에 들어 있는 기존 값이 삭제되고 사용자가 빈 텍스트

필드에서 입력하게 된다. 이 체크박스를 선택 해제하면 기존 값이 텍스트 필드에 남아 있는 상태

에서 사용자가 값을 편집할 수 있다. 이 체크박스는 꼭 선택 해제한 상태로 둔다.

Text Color 필드는 색상 팔레트(왼쪽 클릭 시)와 팝업 메뉴로 구성된다. Text Color는 기본값

인 검은색을 그대로 사용한다.

Adjust to Fit 체크박스는 텍스트 필드의 크기가 줄어들 때 텍스트 크기를 줄여야 할지 설정한

다. 이 체크박스를 선택하면 주어진 공간보다 텍스트의 길이가 길더라도 전체 텍스트를 항상 다

볼 수 있다. 이 체크박스의 오른편에는 최소 텍스트 크기를 지정할 수 있는 텍스트 필드가 있다.

텍스트 필드의 크기와 상관없이 텍스트의 크기는 이 최솟값 미만으로 작아지지 않는다. 최소 크

기를 지정하면 텍스트 크기가 지나치게 작아짐으로 인해 가독성이 떨어지는 것을 막을 수 있다.

텍스트 입력 특성

이어지는 영역에서는 키보드를 보여주는 방법과 텍스트 필드를 사용할 때 키보드가 어떻게 동

작할지를 지정한다. 이 텍스트 필드에서는 이름을 입력받아야 하므로 Capitalize 드롭다운 메뉴

를 Words로 변경해 보통 이름을 입력할 때처럼 모든 단어의 첫 글자를 대문자로 만든다. 이어서

Return Key 팝업 메뉴의 값을 Done으로 바꾸고 나머지 텍스트 입력 특성은 기본값을 그대로

사용한다. Return Key는 키보드의 우측 하단에 있는 키로서 작업 종류에 따라 라벨이 바뀐다.

Page 113: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 89

예를 들어 사파리의 검색 필드에 값을 입력할 경우 이 키의 라벨은 Google이 된다. 이런 특성을

감안해 다른 컨트롤과 화면을 공유하는 텍스트 필드의 경우 Done 정도로 지정하는 게 적절하

다. 나머지 세 팝업 메뉴는 기본값을 그대로 둔다.

Auto-enable Return Key 체크박스가 선택돼 있으면 텍스트 필드에 최소 한 글자를 입력할 때

까지는 리턴 키가 비활성화된다. 여기서는 사용자가 빈 값을 지정할 수 있게 이 체크박스를 선택

해제한 상태로 둔다.

Secure 체크박스는 입력 중인 문자를 텍스트 필드에 그대로 보여줄지 여부를 지정한다. 텍스

트 필드를 비밀번호 필드로 사용할 경우 이 체크박스를 선택하면 된다. 여기서는 이 체크 박스도

선택 해제한 상태로 둔다.

나머지 항목들 . . .

나머지 영역에서는 UIControl에서 상속한 일반적인 컨트롤 어트리뷰트를 설정할 수 있게 해주

지만, 이들 어트리뷰트는 텍스트 필드에는 잘 적용되지 않으며, Enabled 체크박스를 제외하고는

텍스트 필드의 외양에도 영향을 주지 않는다. 예제에 사용된 텍스트 필드는 사용자와 상호작용

할 수 있게 활성화돼 있어야 하므로 나머지 항목들은 모두 그대로 두면 된다.

인스펙터의 마지막 영역은 이미 낯이 익을 것이다. 이미지 뷰의 인스펙터에서도 이와 동일한 이

름의 영역이 있었기 때문이다. 이들 어트리뷰트는 UIView 클래스로부터 상속한 어트리뷰트를

설정하는 영역인데 모든 컨트롤은 UIView의 하위 클래스이므로 두 컨트롤은 같은 어트리뷰트

영역을 사용한다. 하지만 텍스트 필드의 경우 Opaque 체크박스를 선택하지 않는 점에 주의해야

한다. 이렇게 할 경우 입력한 텍스트를 전혀 읽을 수 없기 때문이다. 사실 이 영역에 있는 값들은

기본값을 그대로 사용하면 된다.

두 번째 텍스트 필드에 대한 어트리뷰트 설정

이어서 View 창에서 두 번째 텍스트 필드를 클릭하고 인스펙터로 돌아온다. Placeholder 필드에

서 Type in a number 텍스트를 입력한다. 그런 다음 Text Input Traits에서 Keyboard Type 팝

업 메뉴를 클릭한다. 이 텍스트 필드에서는 문자를 제외한 숫자만 입력받을 것이므로 Number

Pad를 선택한다. 이렇게 하면 사용자에게 숫자만 들어 있는 키보드가 나타나므로 사용자는 알

파벳 문자나 기호, 기타 숫자 이외의 정보를 입력할 수 없다. 숫자 키패드에서는 키보드 자체에 리

턴 키가 없으므로 Return Key를 설정하지 않아도 된다. 따라서 인스펙터 창에서 나머지 정보들

은 모두 기본값을 그대로 사용한다.

Page 114: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

90 l 시작하세요! 아이폰 4 프로그래밍

아웃렛 연결

이제 인터페이스 부분이 모두 끝났으므로 아웃렛만 연결하면 된다. File’s Owner를 각각의 텍스

트 필드로 컨트롤-드래그한 후 각 텍스트 필드에 해당하는 아웃렛을 연결한다. 두 텍스트 필드

를 모두 관련 아웃렛과 연결한 후에는 nib 파일을 저장한다.

키보드 닫기

이제 애플리케이션이 어떻게 동작하는지 직접 확인해 보자. Xcode의 Product 메뉴에서 Run을

선택해 iOS 시뮬레이터에서 애플리케이션을 실행한다. Name 텍스트 필드를 클릭하면 일반 키

보드가 표시될 것이다. 이름을 입력한다. 이어서 Number 필드를 탭하면 숫자 키패드가 보일 것

이다(그림 4-14 참고). 코코아 터치에서는 인터페이스에 텍스트 필드를 추가하는 것만으로 이런

기능을 모두 기본 제공한다.

그림 4-14 | 텍스트 필드나 숫자 필드를 터치하면 키보드가 자동으로 올라온다.

그런데 문제가 생겼다. 키보드가 도통 사라지지 않는 것이다. 이 키보드를 어떻게 없앨 수 있을

까? 독자들 나름대로 방법을 궁리해 여러 가지를 시도해 보자. 독자들이 해결책을 찾는 동안 우

리는 여기서 가만히 기다리겠다.

Page 115: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 91

Done을 탭할 때 키보드 닫기

iOS의 키보드는 물리적인 키보드가 아니라 소프트웨어 기반이므로 사용자가 키보드를 다 사

용한 후 이를 사라지게 하려면 몇 가지 추가 절차가 더 필요하다. 텍스트 키보드에서 사용자가

Done 버튼을 탭하면 Did End On Exit 이벤트가 발생하는데, 이 시점에 텍스트 필드가 자신의

제어권을 포기하게 하면 키보드를 사라지게 할 수 있다. 이를 위해서는 컨트롤러 클래스에 액션

메서드를 추가해야 한다. 다음 코드를 Control_FunViewController.h에 추가하자.

#import <UIKit/UIKit.h>

@interface Control_FunViewController : UIViewController {

UITextField *nameField;

UITextField *numberField;

}

@property (nonatomic, retain) IBOutlet UITextField *nameField;

@property (nonatomic, retain) IBOutlet UITextField *numberField;

- (IBAction)textFieldDoneEditing:(id)sender;

@end

이어서 Control_FunViewController.m으로 이동해 이 메서드를 구현한다. 새로 추가하는

액션 메서드에 코드 한 줄만 넣으면 키보드를 사라지게 할 수 있다. 다음 메서드를 Control_

FunViewController.m에 추가한다.

- (IBAction)textFieldDoneEditing:(id)sender {

[sender resignFirstResponder];

}

2장에서 배운 것처럼 퍼스트 리스폰더는 사용자가 현재 상호작용하는 컨트롤이다. 새로 추가

한 메서드에서는 컨트롤이 퍼스트 리스폰더 상태를 포기하게 하고 사용자가 이전에 작업하던 컨

트롤로 퍼스트 리스폰더 지위를 넘겨주게 했다. 텍스트 필드가 퍼스트 리스폰더 지위를 포기하

면 이와 관련한 키보드도 사라진다.

위에서 수정한 파일 두 개를 모두 저장한다. 이어서 Control_FunViewController.xib을 클릭

해 두 텍스트 필드에서 이 액션 메서드를 호출할 수 있게 인터페이스 빌더를 다시 연다.

인터페이스 빌더에서는 Name 텍스트 필드를 클릭하고 z6을 눌러서 커넥션 인스펙터를 연

다. 이번에는 이전 장에서 사용한 Touch Up Inside 이벤트를 사용하지 않는다. 대신 사용자가 키

보드의 Done 버튼을 탭할 때 발생하는 Did End On Exit 이벤트를 사용한다. Did End On Exit

Page 116: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

92 l 시작하세요! 아이폰 4 프로그래밍

옆에 있는 원을 File’s Owner로 드래그하고 textFieldDoneEditing: 액션을 연결한다. 같은 과정

을 옆의 텍스트에도 똑같이 적용하고 저장한다. 그런 다음 빌드 후 재실행한다.

Did End On Exit에서 드래그를 했는데 드래그를 마칠 수 있는 표시인 하이라이트가 File’s

Owner 아이콘에 생기지 않는 경우에는 nib 파일을 편집하도록 전환하는 과정에서 소스 코드

를 저장하지 안았을 확률이 높다. 이때는 컨트롤러의 헤더 파일을 선택하고 저장한 후 다시 시

도해 본다. 그럼 아마 모든 게 정상 동작할 것이다.

시뮬레이터가 나타나면 Name 필드를 클릭하고 내용을 입력한 다음 Done 버튼을 탭한다. 그

럼 예상한 대로 키보드가 사라질 것이다. 그런데 Number 필드는 어떻게 해야 할까? 숫자 키패드

에는 Done 버튼이 없는데 말이다(그림 4-14 참고).

아쉽지만 모든 키보드 레이아웃에 항상 Done 버튼이 들어 있는 건 아니다. 물론 사용자에게

Name 필드를 다시 탭하고 키보드가 새로 올라오면 Done 버튼을 탭하라고 우길 수도 있다. 하지

만 이 방식은 사용자 친화적이지 못하다. 더구나 가장 사용자 친화적이어야 할 이런 애플리케이

션에서 이런 방식을 사용하는 건 적절치 않다. 그럼 이 상황을 어떻게 처리해야 할지 알아보자.

배경을 터치할 때 키보드 닫기

다른 iOS 애플리케이션에서 이 상황을 어떻게 처리하는지 곰곰이 떠올려보자. 텍스트 필드가

들어 있는 대다수 애플리케이션에서는 다른 능동적 컨트롤이 없는 뷰 영역을 탭하면 키보드가

바로 사라진다. 그럼 이를 어떻게 구현한 것일까?

이에 대한 답을 듣고 나면 미처 생각지 못한 단순한 곳에 답이 있었음을 알고 놀라게 될 것이

다. 뷰 컨트롤러에는 UIViewController에서 상속한 view 속성이 들어 있다. 이 view 속성은 nib

파일의 View 아이콘과도 일치한다. 이 속성은 모든 사용자 인터페이스 항목의 컨테이너 역할을

하는 nib 파일 내의 UIView 인스턴스를 가리킨다. 이 UIView 인스턴스는 사용자 인터페이스에

서 아무런 모양도 하고 있지 않지만 아이폰 창의 전체 영역을 모두 차지하며 나머지 사용자 인터

페이스 객체들의 ‘아래에서’ 자리를 지키고 있다. 이 인스턴스는 주 목적이 다른 뷰와 컨트롤을 보

관하는 것이므로 nib 파일의 컨테이너 뷰라고도 부른다. 본래 의도와 목적상 컨테이너 뷰는 사

용자 인터페이스에서 배경 역할을 한다.

Page 117: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 93

인터페이스 빌더를 활용하면 v iew가 가리키는 객체의 클래스를 변경해 UIView 대신

UIControl 클래스를 내부 클래스로 사용할 수 있다. UIControl은 UIView의 하위 클래스이

므로 view 속성을 UIControl 인스턴스와 연결하더라도 전혀 문제가 되지 않는다. 클래스가 다

른 클래스를 상속할 경우 하위 클래스는 상위 클래스의 좀 더 구체적인 버전일 뿐이라는 사실

을 기억하자. 따라서 UIControl도 여전히 UIView인 것이다. 생성되는 인스턴스를 UIView에서

UIControl로 바꾸고 나면 액션 메서드를 호출할 수 있다. 하지만 이 작업을 하기 전에 배경을 탭

할 때 호출할 액션 메서드부터 작성해야 한다.

이제 컨트롤러 클래스에 액션 메서드를 하나 더 추가해야 한다. 다음 코드를 Control_FunView

Controller.h 파일에 추가한다.

#import <UIKit/UIKit.h>

@interface Control_FunViewController : UIViewController {

UITextField *nameField;

UITextField *numberField;

}

@property (nonatomic, retain) IBOutlet UITextField *nameField;

@property (nonatomic, retain) IBOutlet UITextField *numberField;

- (IBAction)textFieldDoneEditing:(id)sender;

- (IBAction)backgroundTap:(id)sender;

@end

이제 헤더 파일을 저장한다.

다음으로 구현체 파일로 이동해 다음 코드를 추가한다. 이 코드에서는 두 텍스트 필드 모두 퍼

스트 리스폰더 지위를 포기하게 하는 간단한 일을 처리한다. 퍼스트 리스폰더가 아닌 컨트롤에

대해서 resignFirstResponder를 호출한다고 하더라도 전혀 문제가 생기지 않으므로 여기서는

해당 컨트롤이 퍼스트 리스폰더인지 확인을 거치지 않고 두 텍스트 필드 모두에 대해 이 메서드

를 그냥 호출한다.

- (IBAction)backgroundTap:(id)sender {

[nameField resignFirstResponder];

[numberField resignFirstResponder];

}

Page 118: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

94 l 시작하세요! 아이폰 4 프로그래밍

코드를 작성할 때는 헤더 파일과 구현체 파일 사이를 여러 번 오가게 된다. 다행히 파일 바로

이동이라는 편리한 방법 외에 Xcode에서는 두 파일을 빠르게 전환할 수 있는 키보드 단축키

를 제공한다. 기본 단축키는 ^z(컨트롤-커맨드-위 화살표 키)이지만 이는 Xcode의 환경

설정에서 얼마든지 원하는 대로 수정해 사용할 수 있다.

이제 파일을 저장하고 인터페이스 빌더로 돌아간다. 이번에는 nib 뷰의 내부 클래스를 변경해

야 한다. nib 파일의 Objects 영역에는 View 아이콘이 있다(그림 4-15 참고). 이 아이콘은 nib의

메인 뷰로서 나머지 컨트롤과 뷰를 모두 하위 뷰로 갖고 있다.

그림 4-15 | nib의 편집 창에는 세 개의 아이콘이 있다. 이 중 Objects 영역에 있는 View 아이콘은 nib의

콘텐츠 뷰를 나타낸다.

View 아이콘을 한 번 클릭하고 z3 단축키를 사용해 아이덴티티 인스펙터(그림 4-16)를 띄

운다. 아이덴티티 인스펙터는 인터페이스 빌더에서 모든 객체 인스턴스의 내부 클래스를 수정할

수 있는 곳이다.

현재 Class라는 필드에는 UIView가 표시돼 있을 것이다. 이를 UIControl로 바꾼다. 액션 메

서드를 호출할 수 있는 컨트롤들은 모두 UIControl 클래스를 상속해야 하므로 이와 같이 내부

클래스를 변경하면 뷰에서 액션 메서드를 호출할 수 있다. 이런 사실은 z6을 눌러서 커넥션

인스펙터(그림 4-17)를 열어 바로 확인할 수 있다. 이제 앞 장에서 버튼을 액션과 연결할 때 사용

한 이벤트들을 뷰의 커넥션 인스펙터에서도 모두 볼 수 있을 것이다.

Page 119: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 95

그림 4-16 | 아이덴티티 인스펙터에서는 nib에 들어 있는 모든 객체의 내부 클래스를 변경할 수 있다.

그림 4-17 | 뷰의 클래스를 UIView에서 UIControl로 변경함에 따라 표준 이벤트가 발생할 때 액션 메서드

를 실행할 수 있게 됐다.

이어서 Touch Down 이벤트를 File’s Owner 아이콘으로 드래그하고 backgroundTap: 액션을

선택한다. 이제 능동형 컨트롤이 없는 뷰 영역을 터치하면 이 액션 메서드가 실행되고 키보드가

사라질 것이다.

Page 120: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

96 l 시작하세요! 아이폰 4 프로그래밍

노트

여기서 왜 이전 장에서처럼 Touch Up Inside 이벤트를 사용하지 않고 Touch Down 이벤트

를 선택했는지 궁금한 독자도 있을 것이다. 그 이유는 배경은 버튼이 아니기 때문이다. 사용자

의 관점에서 보면 배경은 컨트롤이 아니므로 대다수 사용자는 특정 행동을 취소하기 위해 배

경을 드래그하는 등의 행동을 일절 하지 않는다.

nib 파일을 저장한 후 다시 애플리케이션을 컴파일하고 재실행한다. 이번에는 Done 버튼을 탭

할 때뿐 아니라 능동형 컨트롤이 속하지 않는 다른 영역을 클릭할 때도 키보드가 사라질 것이다.

바로 이것이 사용자가 기대하는 애플리케이션의 동작 방식이다.

이제 이 부분은 모두 완성했으니 이어서 다음 컨트롤 그룹을 다루는 주제로 넘어가자.

슬라이더와 라벨 구현

이제 텍스트 필드를 모두 완성했으므로 슬라이더를 구현해 보자. 이 절에서는 슬라이더의 값에

따라 값이 바뀌는 라벨도 함께 추가한다.

아웃렛과 액션에 대한 판단

슬라이더와 라벨이 필요한 아웃렛 개수가 몇 개일지 생각해 보자. 이번에는 슬라이더 값이 바뀔

때마다 라벨 값도 프로그래밍적으로 함께 바꿔야 하므로 라벨에 대한 아웃렛은 꼭 필요하다. 그

렇다면 슬라이더 아웃렛은 어떨까?

슬라이더가 액션을 실행하면 액션이 실행될 때 액션 메서드는 sender 인자를 통해 슬라이더에

대한 포인터를 얻는다. 슬라이더의 값은 sender로부터 조회할 수 있으므로 슬라이드의 값을 가

져 오기 위해 아웃렛을 선언할 필요는 없다. 그렇다면 슬라이더에는 아웃렛이 전혀 필요 없을까?

다시 말해 슬라이더에서 호출하는 액션 메서드 밖에서 슬라이더 값에 접근할 필요가 있을까?

실제 애플리케이션이라면 슬라이더 값에 접근해야 할 일이 종종 있다. 예를 들어 슬라이더에

존재하는 값을 표시하는 뷰 컨트롤러를 보여줘야 하는 경우가 있을 수 있다. 이때 아웃렛이 없다

면 이 값을 설정할 방법이 없다. 하지만 여기서는 다른 컨트롤에서 슬라이더 값과 동일한 값을 갖

고 있으며 자체 아웃렛 또한 갖고 있으므로 슬라이더 자체에 대한 아웃렛은 전혀 필요 없다.

Page 121: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 97

iOS 기기용 프로그램을 개발할 때는 메모리와 관련해 각별히 주의하는 습관을 들이는 게 좋

다. 물론 포인터는 적은 메모리를 차지하지만 굳이 필요하지 않다면 사용할 이유가 없다. 아울러

사용하지도 않는 포인터를 위해 추가 코드를 작성할 이유도 전혀 없다.

두 컨트롤에 필요한 액션은 쉽게 판단할 수 있다. 슬라이더는 값이 바뀔 때 호출할 액션이 하

나 필요하다. 라벨은 정적이며 사용자가 직접 사용할 수 없으므로 아무런 액션도 호출할 필요가

없다.

아웃렛과 액션의 추가

다음과 같이 Control_FunViewController.h 파일에 아웃렛과 액션을 하나씩 더 추가하자.

#import <UIKit/UIKit.h>

@interface Control_FunViewController : UIViewController {

UITextField *nameField;

UITextField *numberField;

UILabel *sliderLabel;

}

@property (nonatomic, retain) IBOutlet UITextField *nameField;

@property (nonatomic, retain) IBOutlet UITextField *numberField;

@property (nonatomic, retain) IBOutlet UILabel *sliderLabel;

- (IBAction)textFieldDoneEditing:(id)sender;

- (IBAction)backgroundTap:(id)sender;

- (IBAction)sliderChanged:(id)sender;

@end

이번에는 메서드에서 할 일을 정확히 알고 있으므로 Control_FunViewController.m으로 바

로 전환해 속성에 대한 @synthesize를 추가하고 sliderChanged: 메서드를 구현한다.

#import "Control_FunViewController.h"

@implementation Control_FunViewController

@synthesize nameField;

@synthesize numberField;

@synthesize sliderLabel;

- (IBAction)sliderChanged:(id)sender {

UISlider *slider = (UISlider *)sender;

int progressAsInt = (int)(slider.value + 0.5f);

NSString *newText = [[NSString alloc] initWithFormat:@"%d",

progressAsInt];

Page 122: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

98 l 시작하세요! 아이폰 4 프로그래밍

sliderLabel.text = newText;

[newText release];

}

- (IBAction)backgroundTap:(id)sender {

...

sliderChanged: 메서드 내부에서 일어나는 일을 하나씩 살펴보자. 이 메서드에서는 먼저

sender를 UISlider *로 캐스팅한다. 이렇게 하면 코드를 읽기도 좀 더 쉽고 sender를 사용할 때

마다 매번 캐스팅하지 않아도 되므로 편하다. 그런 다음에는 슬라이더의 값을 int로 알아온 다음

가장 가까운 정수 값으로 반올림하기 위해 0.5를 더한다. 이 정수 값은 라벨의 텍스트로 지정할

새로운 문자열을 만드는 데 사용한다. 여기서는 newText에 메모리를 할당했으므로 이를 릴리스

해야 한다. 따라서 이 메서드의 마지막 코드에서는 이 객체를 릴리스한다. 매우 간단한 내용이므

로 이해에 무리가 없을 것이다.

메모리 관리 책임에 대한 얘기가 나온 김에 같이 설명하자면, 앞에서 sliderLabel 속성에 retain

키워드를 추가했으므로 이 속성 또한 반드시 릴리스해줘야 한다. 이를 위해 dealloc 메서드에 다

음 코드를 추가한다.

- (void)dealloc {

[nameField release];

[numberField release];

[sliderLabel release];

[super dealloc];

}

이제 코드상에서의 작업은 끝났으므로 수정 사항을 저장한다. 이제 객체를 인터페이스에 추

가할 차례다.

슬라이더와 라벨의 추가

지금쯤이면 기본 흐름은 익숙할 것이다. 아직 열려 있지 않다면 Control_FunViewController.

xib을 클릭해 인터페이스 빌더를 열고, 이미 열려 있다면 인터페이스 빌더를 바로 살펴본다.

슬라이더를 추가하기 전에 디자인에 조금 여유 공간을 주는 게 좋겠다. 상단 텍스트 필드와 그

위에 있는 이미지 사이의 거리를 정할 때 사용한 파란색 안내선은 실제로는 최소한의 근접 거리

에 권장하는 위치다. 다시 말해 파란색 안내선은 “이 선보다 더 가까이 다가가지 마세요” 정도의

의미로 사용된다. 그림 4-1을 참고해 두 텍스트 필드와 라벨을 조금 더 아래로 움직이자. 그런 후

에 슬라이더를 추가한다.

Page 123: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 99

라이브러리에서 슬라이더를 가져와 숫자 텍스트 필드 아래에 배치하고 가로 영역을 거의 다 차

지하게 하되, 모두 차지하지는 않게끔 크기를 늘린다. 이때 라벨 왼쪽에 작은 여유 공간을 둔다.

이번에도 그림 4-1을 보면서 작업을 진행한다. 새로 추가한 슬라이더를 클릭해 선택한 후 z4

를 눌러서 인스펙터를 연다. 이 경우 인스펙터는 그림 4-18과 같은 형태로 보일 것이다.

그림 4-18 | 슬라이더에 대한 어트리뷰트를 보여주는 인스펙터

슬라이더를 사용하면 특정 범위 내에서 숫자를 선택할 수 있는데, 인터페이스 빌더를 활용하

면 슬라이더의 범위와 초기 값을 모두 설정할 수 있다. 최소 값은 1, 최대 값은 100으로 설정하고

초기 값은 50으로 설정한다. 여기서는 이 값들만 잘 설정하면 된다.

이어서 라이브러리에서 라벨을 가져와 슬라이더 옆에 배치한다. 이때 파란색 안내선을 활용해

슬라이더와 수직 위치를 맞추고 왼쪽 모서리를 뷰의 왼쪽 마진과 정렬한다(그림 4-19 참고).

그림 4-19 | 슬라이더와 라벨의 배치

Page 124: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

100 l 시작하세요! 아이폰 4 프로그래밍

새로 배치한 라벨을 더블클릭하고 텍스트를 Label에서 100으로 바꾼다. 100 값은 슬라이더

가 가질 수 있는 가장 큰 값이므로 이 값을 활용하면 슬라이더의 올바른 너비를 판단할 수 있다.

‘100’은 ‘Label’보다 글자가 짧기 때문에 이 경우 라벨의 우측 중간 리사이즈 점을 잡아 왼쪽으로

드래그해야 한다. 이때 텍스트가 작아지기 전에 리사이즈를 멈춰야 한다. 텍스트가 작아지기 시

작했다면, 텍스트가 본래 크기로 돌아올 때까지 리사이즈 점을 다시 오른쪽으로 움직이면 된다.

물론 이때도 z= 단축키를 눌러서 size-to-�t 옵션을 사용하거나 Editor 메뉴에서 Size to Fit을

선택해도 된다. 이어서 슬라이더를 한 번 클릭해 선택한 후 파란색 안내선에서 멈추라고 할 때까

지 왼쪽 리사이즈 점을 왼쪽으로 드래그한다.

이번에는 라벨을 다시 한 번 더블클릭하고 값을 50으로 바꾼다. 이 값은 슬라이더의 시작 값이

므로 실행 시점에 인터페이스가 제대로 보이게 하려면 라벨 값을 이 값으로 다시 수정해야 한다.

애플리케이션 실행 후 사용자가 슬라이더를 사용하기 시작하면 방금 작성한 코드로 인해 라벨

이 올바른 슬라이더 값을 계속 보여줄 것이다.

액션과 아웃렛의 연결

이제 이들 두 컨트롤에 대해 할 일은 액션과 아웃렛을 연결하는 것뿐이다. 액션과 아웃렛 연결

은 이미 독자들이 익숙한 내용이니 바로 작업을 시작하자. 혹시 방법을 까먹은 독자들이 있다면

File’s Owner 아이콘에서 방금 추가한 라벨로 컨트롤-드래그한 후 sliderLabel을 선택한다. 그런

다음 슬라이더를 한 번 클릭하고 z6을 눌러서 커넥션 인스펙터를 연다. 그리고 드래그를 해

야 하는데 이번에는 Touch Up Inside를 사용하지 않는 대신 Value Changed를 사용해야 한다.

Value Changed를 File’s Owner로 드래그한 후 sliderChanged를 선택한다.

nib 파일을 저장하고 애플리케이션을 실행해 슬라이더를 테스트한다. 슬라이더를 움직이면

라벨 텍스트가 실시간으로 바뀌는 것을 볼 수 있을 것이다. 이로써 또 다른 애플리케이션 영역을

완성했다. 이제 스위치를 구현하는 법을 살펴보자.

스위치, 버튼, 분할 컨트롤의 구현

다시 Xcode로 돌아온다. 벌써 조금 정신 없는 기분이 들 것이다. 이렇게 프로그램을 왔다 갔다

하면서 작업하는 게 조금 이상해 보일 수도 있다. 하지만 Xcode에서 소스 코드를 편집하고 인터

페이스 빌더에서 인터페이스를 만지작거린 후 중간 중간 적절한 iOS 시뮬레이터에서 애플리케이

션을 테스트하는 작업은 iOS 애플리케이션을 개발할 때 흔히 볼 수 있는 개발 과정이다.

Page 125: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 101

이 애플리케이션에는 두 개의 스위치가 있다. 스위치는 on과 o�라는 두 개의 상태만을 갖는 작

은 컨트롤이다. 이 애플리케이션에는 스위치를 감추고 보여줄 수 있는 분할 컨트롤도 들어 있다.

이 컨트롤과 더불어 분할 컨트롤의 우측을 탭할 때 보여줄 버튼도 추가한다. 이제 이들 컨트롤을

하나씩 구현해 보자.

아웃렛과 액션의 추가

분할 컨트롤은 코드상에서 속성을 변경할 일이 없으므로 아웃렛이 필요 없다. 하지만 스위치

의 경우 한 스위치의 값이 다른 스위치의 값을 바꾸므로 아웃렛이 필요하다. 선택된 스위치는

sender를 통해 접근할 수 있지만 다른 스위치에 접근하려면 아웃렛을 사용해야 한다. 또 이 애플

리케이션에서는 추가할 버튼에 대한 아웃렛도 필요하다.

분할 컨트롤은 스위치를 감추거나 보여줄 액션 메서드를 호출한다. 또 두 스위치 중 하나를 탭

할 때 호출할 액션도 필요하다. 이 예제에서는 3장에서 두 버튼에 대해 한 것처럼, 두 스위치가 같

은 액션 메서드를 호출하게 할 것이다. Control_FunViewController.h에서 아래 세 개의 아웃렛

과 두 개의 액션을 추가하자.

#import <UIKit/UIKit.h>

#define kSwitchesSegmentIndex 0

@interface Control_FunViewController : UIViewController {

UITextField *nameField;

UITextField *numberField;

UILabel *sliderLabel;

UISwitch *leftSwitch;

UISwitch *rightSwitch;

UIButton *doSomethingButton;

}

@property (nonatomic, retain) IBOutlet UITextField *nameField;

@property (nonatomic, retain) IBOutlet UITextField *numberField;

@property (nonatomic, retain) IBOutlet UILabel *sliderLabel;

@property (nonatomic, retain) IBOutlet UISwitch *leftSwitch;

@property (nonatomic, retain) IBOutlet UISwitch *rightSwitch;

@property (nonatomic, retain) IBOutlet UIButton *doSomethingButton;

- (IBAction)textFieldDoneEditing:(id)sender;

- (IBAction)backgroundTap:(id)sender;

- (IBAction)sliderChanged:(id)sender;

- (IBAction)toggleControls:(id)sender;

Page 126: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

102 l 시작하세요! 아이폰 4 프로그래밍

- (IBAction)switchChanged:(id)sender;

- (IBAction)buttonPressed;

@end

잠시 후 작성할 코드에서는 UISegmentedControl의 selectedSegmentIndex 속성을 참조할

것이다. 이 속성은 현재 선택된 영역을 알려주는 속성이다. 이 속성값은 정수 값이다. 스위치 영

역의 인덱스 값은 0이다. 코드에서는 이 0 값을 그냥 사용하는 대신 코드를 좀 더 이해하기 쉽게

kSwitchesSegmentIndex 상수를 사용한다. 0 값을 그냥 사용할 경우 몇 개월만 지나도 이 값에

어디에 쓰이는지 까먹을 수 있기 때문이다.

Control_FunViewController.m에서 다음 코드를 추가한다.

#import "Control_FunViewController.h"

@implementation Control_FunViewController

@synthesize nameField;

@synthesize numberField;

@synthesize sliderLabel;

@synthesize leftSwitch;

@synthesize rightSwitch;

@synthesize doSomethingButton;

- (IBAction)toggleControls:(id)sender {

if ([sender selectedSegmentIndex] == kSwitchesSegmentIndex)

{

leftSwitch.hidden = NO;

rightSwitch.hidden = NO;

doSomethingButton.hidden = YES;

}

else

{

leftSwitch.hidden = YES;

rightSwitch.hidden = YES;

doSomethingButton.hidden = NO;

}

}

- (IBAction)switchChanged:(id)sender {

UISwitch *whichSwitch = (UISwitch *)sender;

BOOL setting = whichSwitch.isOn;

[leftSwitch setOn:setting animated:YES];

Page 127: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 103

[rightSwitch setOn:setting animated:YES];

}

- (IBAction)buttonPressed {

// 할 일 : 액션 시트와 경고창 구현

}

- (IBAction)sliderChanged:(id)sender {

...

여기서 추가한 첫 번째 메서드인 toggleControls:는 분할 컨트롤을 탭할 때마다 호출된다. 이

메서드에서는 선택된 영역을 확인하고 필요에 따라 스위치를 감추고 버튼을 보여주거나, 스위치

를 보여주고 버튼을 감춘다.

두 번째로 추가한 메서드인 switchChanged:는 두 스위치 중 하나를 탭할 때 호출된다. 이 메

서드에서는 사용자가 탭한 스위치를 나타내는 sender 값을 가져오고 이 값을 활용해 두 스위치

를 설정한다. 이때 sender는 항상 le�Switch이거나 rightSwitch 중 하나인데 왜 두 스위치를 모

두 설정하는지 궁금한 독자도 있을 것이다. 이렇게 하는 이유는 매번 이 메서드를 호출한 스위치

를 판단하고 나머지 스위치를 설정하는 것보다는 차라리 두 스위치 값을 매번 설정하는 게 일이

더 적기 때문이다. 이렇게 하면 이 메서드를 어떤 스위치에서 호출하더라도 스위치가 항상 올바

른 값을 갖게 되고, 값을 다시 설정하는 경우에는 아무런 변화도 일어나지 않는다.

스위치 값을 바꿀 때 인자로 BOOL 값을 받는 setOn:animated: 메서드를 호출하는 부분을 주

의해서 보자. 첫 번째 매개변수는 스위치를 켜고 끌지 판단하는 데 사용된다. 두 번째 매개변수

는 마치 사람이 실제로 버튼을 누른 것처럼 버튼이 천천히 슬라이드될지 또는 새로운 위치로 갑

자기 움직일지 지정하는 매개변수다. 첫 번째 매개변수 값으로는 현재 상태를 기반으로 판단한

새로운 on/o� 값을 넘겨준다. 두 번째 매개변수 값으로는 스위치가 부드럽게 슬라이드되면 멋진

효과가 나오고 iOS 기기의 사용자들은 이런 시각적인 피드백에 대한 기대가 크므로 항상 YES를

넘겨준다. 물론 결과 차이를 확인해 보기 위해 NO를 지정해서 테스트하는 것도 괜찮지만 꼭 그

럴 만한 이유가 없다면 보통은 사용자들이 UI의 변화를 인식할 수 있게 프로그래밍적으로 UI

변화에 애니메이션을 가미하는 게 더 좋다.

세 번째로 추가한 메서드인 buttonPressed는 버튼을 누를 때 호출된다. 이 메서드는 아직은 구

현하지 않지만 나중에 구현할 수 있게 지금은 스텁 메서드 형태로만 선언해 두었다.

여기서는 세 개의 아웃렛을 선언했으므로 dealloc 메서드에서는 이들 아웃렛을 모두 릴리스해

야 한다. 다음 코드를 Control_FunViewController.m에 있는 기존 dealloc 메서드에 추가하자.

Page 128: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

104 l 시작하세요! 아이폰 4 프로그래밍

- (void)dealloc {

[nameField release];

[numberField release];

[sliderLabel release];

[leftSwitch release];

[rightSwitch release];

[doSomethingButton release];

[super dealloc];

}

스위치, 버튼, 분할 컨트롤의 추가

다음으로 분할 컨트롤과 분할 컨트롤에서 토글하는 스위치 및 버튼을 추가하자. 인터페이스 빌

더의 라이브러리에서 분할 컨트롤을 드래그(그림 4-20 참고)해서 View 창의 슬라이더 위치보다

조금 아래 놓는다.

그림 4-20 | 라이브러리에 있는 분할 컨트롤

그림 4-21과 같이 분할 컨트롤의 너비가 뷰의 왼쪽 파란색 안내선부터 오른쪽 파란색 안내선

에 닿을 때까지 분할 컨트롤의 크기를 늘린다. 커서를 분할 컨트롤의 First 단어 위에 올려놓고

더블클릭한다. 그럼 해당 영역의 제목을 수정할 수 있는데, 그림 4-21과 같이 제목을 First에서

Switches로 바꾼다. 그런 다음 Second 영역도 마찬가지로 Button으로 바꾼다.

두 개의 라벨 스위치 추가

라이브러리에서 스위치를 가져와 뷰에 놓는다. 스위치를 분할 컨트롤 아래 두고 왼쪽 마진에 맞

춰 정렬한다(그림 4-22). 두 번째 스위치를 라이브러리에서 드래그해 오른쪽 마진에 맞추고 첫 번

째 스위치와 세로 정렬한다.

Page 129: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 105

그림 4-21 | 분할 컨트롤 영역의 이름 바꾸기

그림 4-22 | 뷰에 스위치를 추가한 모습

Page 130: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

106 l 시작하세요! 아이폰 4 프로그래밍

옵션() 키를 누른 상태에서 인터페이스 빌더에서 객체를 드래그하면 해당 항목의 복사본을

만들 수 있다. 동일한 객체를 여러 개 생성할 경우에는 매번 라이브러리로부터 하나씩 객체를

드래그하는 것보다 옵션-드래그 방식이 훨씬 편하다.

스위치 아웃렛과 액션의 연결

버튼을 추가하기 전에 스위치를 le�Switch 및 rightSwitch 아웃렛과 연결해 보겠다. 잠시 후 추

가할 버튼은 스위치 위에 둘 생각인데, 버튼을 추가하고 나면 스위치를 컨트롤-드래그하기가 어

려워지므로 여기서는 버튼을 추가하기 전에 스위치 연결을 먼저 마무리하려고 한다. 버튼과 스

위치는 동시에 보일 일이 없으므로 둘을 모두 같은 위치에 배치하더라도 전혀 문제될 것이 없다.

File’s Owner를 컨트롤-드래그해 각각의 스위치에 연결하고 le�Switch 또는 rightSwitch 아웃

렛으로 적절히 연결한다.

이번에는 왼쪽 스위치를 클릭해 선택하고 z6 단축키를 눌러서 커넥터 인스펙터를 연다.

Value Changed 이벤트를 File’s Owner 아이콘으로 드래그한 후 switchChanged: 액션을 선택

한다. 같은 방식으로 다른 쪽 스위치도 액션을 연결한다.

분할 컨트롤을 클릭해 선택하고 커넥션 인스펙터에서 Value Changed 이벤트를 찾는다. 이벤

트 오른쪽에 있는 원을 File’s Owner 아이콘으로 드래그하고 toggleControls: 액션 메서드를 선

택한다.

버튼 추가

이어서 라이브러리에서 Round Rect Button을 뷰로 드래그한다. 이 버튼은 왼쪽 마진과 두 스위

치의 세로 중심에 맞춰 정렬한다(그림 4-23).

이번에는 오른쪽 가운데에 있는 리사이즈 핸들을 잡아서 파란색 안내선에서 오른쪽 마진을

표시하는 위치까지 핸들을 드래그한다. 이렇게 하면 버튼이 두 스위치의 전체 영역을 모두 덮을

것이다(그림 4-24).

Page 131: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 107

그림 4-23 | Round Rect Button을 기존 스위치 위에 추가하는 모습

그림 4-24 | Round Rect Button의 위치와 크기를 조정하고 나면 기존 스위치들이 완전히 가려진다.

버튼을 더블클릭하고 라벨을 Do Something으로 지정한다. 분할 컨트롤은 처음에 Switches

영역이 기본 선택돼 있으므로 처음 실행할 때는 이 버튼을 숨겨야 한다. z4를 눌러서 어트리

뷰트 인스펙터를 연 후 가장 하단 영역에서 Hidden 체크박스를 클릭한다.

Page 132: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

108 l 시작하세요! 아이폰 4 프로그래밍

버튼 아웃렛과 액션의 연결

File’s Owner 아이콘을 컨트롤-드래그해 새 버튼에 연결하고 doSomethingButton 아웃렛을 선

택한다. 그런 다음 z2를 눌러서 커넥션 인스펙터를 연다. Touch Up Inside 옆에 있는 원을 드

래그해 File’s Owner에 드롭하고 buttonPressed 액션을 선택한다.

이제 작업 내용을 저장한다.

Xcode에서 애플리케이션을 실행해 테스트한다. 이제 분할 컨트롤을 사용할 수 있을 것이다.

Switches 영역을 탭하면 두 개의 스위치가 보일 것이다. 두 스위치 중 하나를 탭하면 두 스위치 모

두 토글될 것이다. Button 영역을 탭하면 스위치가 사라지고 대신 Do Something 버튼이 보일 것

이다. 아직까지는 메서드를 구현하지 않았으므로 이 버튼을 탭하더라도 아무 일도 일어나지 않

는다. 이제 이 작업을 처리해 보자.

액션 시트와 경고창의 구현

액션 시트와 경고창은 둘 다 사용자에게 피드백을 전달하는 용도로 사용된다.

액션 시트는 둘 이상의 항목 가운데 사용자가 하나를 선택하게 할 때 사용한다. 액션 시트는

화면 하단에서부터 올라오며 사용자가 선택할 수 있는 여러 버튼을 보여준다(그림 4-3 참고). 사

용자는 이들 버튼 중 하나를 탭하기 전까지는 애플리케이션을 사용할 수 없다. 액션 시트는 종종

위험 요소가 있거나 객체를 삭제하는 등의 돌이킬 수 없는 작업을 수행할 때 사용자의 확인을 거

치는 용도로 사용한다.

경고창은 화면 중간에 파란색의 모서리가 둥근 사각형 형태로 나타난다(그림 4-4). 액션 시트

와 마찬가지로 경고창은 사용자가 애플리케이션을 계속 사용하기 전에 사용자의 대답을 받는 용

도로 사용한다. 경고창은 중요한 일이나 특별한 일이 일어났을 때 사용자에게 이를 알려주는 용

도로 곧잘 사용된다. 액션 시트와 달리 경고창은 한 개의 버튼만을 주로 보여주는데, 둘 이상의

응답 가운데 하나를 선택해야 할 경우에는 옵션을 통해 여러 버튼을 보여줄 수 있다.

노트

사용자가 애플리케이션을 계속 사용하기 전에 사용자가 뭔가를 선택해야 하는 뷰를 모달 뷰라

고 부른다.

Page 133: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 109

액션 시트 델리게이트 메서드의 프로토콜 구현 선언

3장에서 애플리케이션 델리게이트에 대해 설명한 내용을 기억할 것이다. 코코아 터치에서 델리

게이트를 사용하는 클래스가 UIApplication만 있는 게 아니다. 사실 델리게이트를 통한 이런 작

업 위임은 코코아 터치에서는 일반적인 디자인 패턴이다. 액션 시트와 경고창은 둘 다 델리게이

트를 활용해 자신이 사라지면서 어떤 객체에게 정보를 알려줘야 할지 알게 된다. 예제 애플리케

이션에서도 액션 시트가 사라질 때 이를 통보받아야 한다. 하지만 예제의 경고창은 단순히 사용

자에게 정보를 알려줄 뿐 실제로 선택을 이끌어내는 게 아니므로 경고창이 사라지는 시점은 굳

이 알 필요가 없다.

컨트롤러 클래스를 액션 시트의 델리게이트로 활용하려면 컨트롤러가 UIActionSheet

Delegate라는 프로토콜을 따르게 해야 한다. 컨트롤러가 프로토콜을 따르게 하려면 클래스 선

언에서 상위 클래스명 다음에 꺽쇠 괄호 안에 프로토콜의 이름을 추가하면 된다.

다음 코드를 Control_FunViewController.h에 추가한다.

#import <UIKit/UIKit.h>

#define kSwitchesSegmentIndex 0

@interface Control_FunViewController : UIViewController

<UIActionSheetDelegate> {

UITextField *nameField;

UITextField *numberField;

UILabel *sliderLabel;

...

액션 시트 보여주기

이제 Control_FunViewController.m으로 이동해 버튼의 액션 메서드를 구현한다. 여기서는 기

존 메서드와 더불어 또 다른 메서드를 구현해야 한다. 액션 시트가 사라질 때 이에 대한 알림을

받으려면 UIActionSheetDelegate 메서드를 구현해야 한다.

Control_FunViewController.m에서 수정할 buttonPressed 메서드의 내용은 다음과 같다.

- (IBAction)buttonPressed {

// TODO: Implement Action Sheet and Alert

UIActionSheet *actionSheet = [[UIActionSheet alloc]

initWithTitle:@"Are you sure?"

delegate:self

Page 134: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

110 l 시작하세요! 아이폰 4 프로그래밍

cancelButtonTitle:@"No Way!"

destructiveButtonTitle:@"Yes, I’m Sure!"

otherButtonTitles:nil];

[actionSheet showInView:self.view];

[actionSheet release];

}

다음으로 Control_FunViewController.m에서 buttonPressed 다음에 아래 메서드를 추가

한다.

- (void)actionSheet:(UIActionSheet *)actionSheet

didDismissWithButtonIndex:(NSInteger)buttonIndex

{

if (buttonIndex != [actionSheet cancelButtonIndex])

{

NSString *msg = nil;

if (nameField.text.length > 0)

msg = [[NSString alloc] initWithFormat:

@"You can breathe easy, %@, everything went OK.",

nameField.text];

else

msg = @"You can breathe easy, everything went OK.";

UIAlertView *alert = [[UIAlertView alloc]

initWithTitle:@"Something was done"

message:msg

delegate:self

cancelButtonTitle:@"Phew!"

otherButtonTitles:nil];

[alert show];

[alert release];

[msg release];

}

}

그럼 이들 메서드에서 하는 일이 정확히 뭘까? 먼저 buttonPressed 액션 메서드에서는

UIActionSheet 객체에 메모리를 할당하고 초기화한다. UIActionSheet는 (혹시 모르는 독자들

을 위해 설명하자면) 액션 시트를 나타내는 객체다.

UIActionSheet *actionSheet = [[UIActionSheet alloc]

initWithTitle:@"Are you sure?"

delegate:self

Page 135: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 111

cancelButtonTitle:@"No Way!"

destructiveButtonTitle:@"Yes, I’m Sure!"

otherButtonTitles:nil];

이 클래스의 초기자 메서드에서는 다양한 매개변수를 받는다. 이들 매개변수를 하나씩 차례

대로 살펴보자. 첫 번째 매개변수는 표시할 제목이다. 그림 4-3을 다시 참고하면 액션 시트의 상

단에 제목이 표시되고 있음을 볼 수 있다.

두 번째 인자는 액션 시트에 대한 델리게이트다. 액션 시트의 델리게이트는 액션 시트의 버튼

을 탭할 때 이에 대한 알림을 받는다. 더 구체적으로 설명하자면 이 경우 델리게이트의 action

Sheet:didDismissWithButtonIndex: 메서드가 호출된다. 여기서는 델리게이트 매개변수 값으로

self를 전달함으로써 컨트롤러에서 구현한 actionSheet:didDismissWithButtonIndex: 메서드

가 바로 호출되게 했다.

다음으로 사용자가 액션 시트 사용을 취소하고자 할 때 탭할 버튼에 대한 제목을 넘겨준다.

모든 액션 시트는 항상 취소 버튼을 갖고 있어야 하는데, 취소 버튼에 대한 제목은 각 상황에 따

라 얼마든지 자유롭게 지정할 수 있다. 액션 시트는 선택할 항목이 없을 때는 사용하지 않는 게

좋다. 선택할 항목이 없는 상황에서 사용자에게 뭔가를 알려줄 때는 경고창을 사용하는 게 더

좋다.

다음으로 넘겨주는 매개변수는 확인 버튼으로서 이 버튼은 ‘예, 계속 하세요’ 버튼 정도로 생

각하면 된다. 물론 이때도 원하는 제목을 얼마든지 지정할 수 있다.

마지막 매개변수는 액션 시트에 보여줄 다른 버튼의 숫자를 나타낸다. 마지막 매개변수로는 원

하는 개수만큼 값을 넘겨줄 수 있는데 이는 오브젝티브-C 언어의 장점 중 하나다. 액션 시트에서

두 개의 버튼을 더 보여주고 싶다면 다음과 같이 하면 된다.

UIActionSheet *actionSheet = [[UIActionSheet alloc]

initWithTitle:@"Are you sure?"

delegate:self

cancelButtonTitle:@"No Way!"

destructiveButtonTitle:@"Yes, I’m Sure!"

otherButtonTitles:@"Foo", @"Bar", nil];

이 코드에서는 총 4개의 버튼이 들어 있는 액션 시트를 만든다. otherButtonTitles 매개변수로

는 원하는 인자를 얼마든지 추가할 수 있지만 마지막 인자로는 항상 nil을 넘겨줘야 한다. 물론

사용할 수 있는 화면 크기의 제약으로 인해 실질적으로 보여줄 수 있는 버튼의 수는 몇 개 정도

로 제한된다.

Page 136: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

112 l 시작하세요! 아이폰 4 프로그래밍

이어서 액션 시트를 생성하고 액션 시트를 보여준다.

[actionSheet showInView:self.view];

액션 시트는 항상 부모를 갖고 있다. 액션 시트의 부모는 항상 현재 사용자에게 보이는 뷰가 돼

야 한다. 이 예제의 경우 인터페이스 빌더에서 디자인한 뷰를 부모로 지정하기 위해 self.view를

사용했다. 이때 오브젝티브-C 언어의 점 표기법을 유심히 살펴보자. self.view는 view 속성의 값

을 반환하는 접근자를 사용한 것으로 [self view]와 같다.

그럼 왜 view를 사용하지 않고 self.view를 사용할까? 그 이유는 view가 UIViewController

클래스의 private 인스턴스 변수이므로 접근자를 통해 접근해야 하기 때문이다.

끝으로 액션 시트를 다 사용한 후에는 액션 시트를 릴리스한다. 물론 사용자가 액션 시트에서

버튼을 탭할 때까지는 액션 시트가 남아 있으니 걱정하지 않아도 된다.

액션 시트 델리게이트의 활용

지금까지의 내용은 그리 어렵지 않았을 것이다. 단 몇 줄의 코드 만으로 앞에서는 액션 시트를 보

여주고 사용자가 결정을 내리게 했다. iOS에서는 추가 코드를 작성하지 않더라도 자동으로 액션

시트에 애니메이션까지 적용해준다. 이제 사용자가 탭한 버튼을 판단해 보자. 방금 전에 구현한

actionSheet:didDismissWithButtonIndex 메서드는 UIActionSheetDelegate의 메서드 중 하

나이고, 앞에서 액션 시트의 델리게이트로 self를 지정했으므로 사용자가 액션 시트에서 버튼을

탭하면 이 메서드가 자동으로 호출될 것이다.

인자인 buttonIndex는 사용자가 실제로 탭한 버튼을 알려준다. 그런데 어떤 버튼 인덱스가

취소 버튼을 참조하고 어떤 버튼 인덱스가 확인 버튼을 참조하는지 어떻게 알 수 있을까? 다행

히 델리게이트 메서드에서는 액션 시트를 나타내는 UIActionSheet 객체에 대한 참조를 받는

다. 이를 통해 액션 시트 객체에 접근하면 어떤 버튼이 취소 버튼인지 알 수 있다. 이 경우 간단히

UIActionSheet 객체의 속성 중 하나인 cancelButtonIndex를 확인하면 된다.

if (buttonIndex != [actionSheet cancelButtonIndex])

이 코드에서는 사용자가 취소 버튼을 탭한 경우를 제외시킨다. 앞에서는 사용자에게 두 개의

버튼 옵션을 부여했으므로 사용자가 취소 버튼을 탭하지 않았다면 사용자는 확인 버튼을 탭했

을 것이므로 액션 시트에서 작업을 계속 진행해도 된다. 사용자가 취소 버튼을 탭하지 않았다면

먼저 사용자에게 보여줄 새로운 문자열을 생성한다. 실제 애플리케이션이라면 사용자가 요청한

Page 137: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 113

내용의 처리를 이곳에서 한다. 하지만 이 예제에서는 간단한 작업 내용을 보여주기 위해 경고창

을 사용해 사용자에게 정보를 알려주는 처리만 한다.

사용자가 상단 텍스트 필드에 이름을 입력했다면 이 이름을 가져와 이를 경고창에서 보여줄

메시지에 사용한다. 상단 텍스트 필드에 이름이 없는 경우에는 일반적인 메시지를 보여준다.

NSString *msg = nil;

if (nameField.text.length > 0)

msg = [[NSString alloc] initWithFormat:

@"You can breathe easy, %@, everything went OK.",

nameField.text];

else

msg = @"You can breathe easy, everything went OK.";

다음 코드는 어느 정도 낯이 익을 것이다. 경고창 뷰와 액션 시트는 생성하는 방법과 사용 방

법이 매우 비슷하기 때문이다.

UIAlertView *alert = [[UIAlertView alloc]

initWithTitle:@"Something was done"

message:msg

delegate:nil

cancelButtonTitle:@"Phew!"

otherButtonTitles:nil];

경고창에서도 표시할 제목을 먼저 넘겨준다. 다음으로 방금 생성한 상세 메시지도 함께 인자

로 넘겨준다. 경고창도 델리게이트를 갖고 있는데 만일 경고창 뷰가 사라지는 시점을 알아야 하

거나 사용자가 경고창 뷰에서 어떤 버튼을 탭했는지 알아야 할 때는 앞의 액션 시트에서 한 것처

럼 델리게이트로 self를 지정하면 된다. 이처럼 델리게이트를 지정하는 경우에는 컨트롤러 클래

스에서 UIAlertViewDelegate 프로토콜도 따르도록 지정해야 하고, 이 프로토콜의 메서드를 한

개 이상 구현해야 한다. 하지만 이 예제에서는 어떤 일이 있어났다는 사실만 사용자에게 알려줄

뿐더러 경고창의 버튼도 한 개뿐이다. 이때는 사용자가 어떤 버튼을 탭하든 상관없고 또 이미 어

떤 버튼을 탭했는지도 알고 있으므로 사용자가 경고창 뷰를 사라지게 하더라도 이에 대한 알림

을 받지 않는다는 의미로 델리게이트를 nil로 지정했다.

액션 시트와 달리 경고창 뷰는 특정 뷰에 연결되지 않는다. 따라서 경고창 뷰를 보여줄 때는 부

모 뷰를 지정하지 않고 그냥 뷰를 보여준다. 경고창 뷰를 보여준 후 메모리 정리까지 깔끔히 하면

경고창과 관련한 작업은 모두 끝난다. 파일을 저장하고 빌드해서 실행한 후 전체 애플리케이션

을 테스트해 보자.

Page 138: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

114 l 시작하세요! 아이폰 4 프로그래밍

버튼 꾸미기

실행 중인 애플리케이션을 그림 4-2와 비교해 보면 재미있는 차이점을 볼 수 있을 것이다. 아마

Do Something 버튼이 그림과는 다르게 보이고 또 액션 시트에 있는 버튼이나 다른 iOS 애플리

케이션에 있는 버튼과도 모양이 달라 보일 것이다. 기본 원형 사각형 버튼은 모양이 그렇게 예쁘

지 않다. 애플리케이션을 마무리하기 전에 이 점을 손보자.

iOS 기기에서 대부분의 버튼은 이미지를 활용해 그린다. 그렇다고 모든 버튼에 대해 이미지 편

집기에서 이미지를 직접 생성해야 한다는 뜻은 아니니 걱정하지 않아도 된다. 다만 버튼을 그릴

때 iOS에서 사용할 템플릿 이미지의 종류만 지정하면 된다.

이때 애플리케이션이 샌드박스에서 실행된다는 사실을 꼭 기억해야 한다. 이 말은 iOS 기기에

설치된 다른 애플리케이션에서 사용 중인 템플릿 이미지에 접근할 수 없다는 뜻으로, 필요한 이

미지가 있다면 모두 애플리케이션의 번들 내에 포함시켜야 한다는 뜻이다. 그럼 이미지 템플릿을

어디서 가져올 수 있을까?

다행히 애플에서는 다양한 이미지 템플릿을 제공하고 있다. 이들 이미지는 iOS 레퍼런스 라이

브러리에 들어 있는 UICatalog라는 iOS 예제 애플리케이션에서 얻을 수 있다.

http://developer.apple.com/library/ios/#samplecode/

UICatalog/Introduction/Intro.html

또는 책의 프로젝트 압축 파일에 들어 있는 04 - Control Fun 폴더에서 이미지를 그냥 복사해

사용해도 된다. 애플의 예제 코드 라이선스에서는 이들 이미지의 사용과 배포를 명시적으로 허

용하고 있으므로 이런 이미지는 애플리케이션에서 마음껏 사용할 수 있다.

04 - Control Fun 폴더나 UICatalog 프로젝트 폴더의 Images 하위 폴더에서 이미지를 Xcode

프로젝트로 드래그해 blueButton.png와 whiteButton.png 이미지를 추가하자.

두 이미지 중 하나를 Preview.app 앱이나 이미지 편집 프로그램에서 열어보면 이미지 내용이

별다른 게 없고 다만 버튼에 이미지를 사용하기 위한 간단한 트릭만 들어 있는 것을 볼 수 있다.

인터페이스 빌더로 돌아가서 Do Something 버튼을 한 번 클릭하고 z4 단축키를 사용

해 어트리뷰트 인스펙터를 연다. 어트리뷰트 인스펙터에서 첫 번째 팝업 메뉴를 사용해 타입을

Rounded Rect에서 Custom으로 바꾼다. 어트리뷰트 인스펙터에서는 버튼에 대한 이미지를 지

정하는 옵션도 볼 수 있다. 하지만 이런 이미지 템플릿은 다루는 방법이 이미지와는 조금 다르므

로 여기서는 이미지를 직접 지정하지 않는다. 이제 nib 파일을 저장한다.

Page 139: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 115

viewDidLoad 메서드의 활용

컨트롤러 클래스의 상위 클래스인 UIViewController에는 nib 파일에서 생성한 객체를 수정해

야 할 때 오버라이드할 수 있는 viewDidLoad 메서드가 들어 있다. 이미지 템플릿의 경우 인터페

이스 빌더에서 원하는 작업을 모두 마무리할 수 없으므로 여기서는 viewDidLoad 메서드를 활

용하겠다. Control_FunViewController.m 파일에서 다음 메서드를 추가하자. 작업을 모두 마치

면 이 메서드에서 하는 일을 설명하겠다.

- (void)viewDidLoad

{

UIImage *buttonImageNormal = [UIImage imageNamed:@"whiteButton.png"];

UIImage *stretchableButtonImageNormal = [buttonImageNormal

stretchableImageWithLeftCapWidth:12 topCapHeight:0];

[doSomethingButton setBackgroundImage:stretchableButtonImageNormal

forState:UIControlStateNormal];

UIImage *buttonImagePressed = [UIImage imageNamed:@"blueButton.png"];

UIImage *stretchableButtonImagePressed = [buttonImagePressed

stretchableImageWithLeftCapWidth:12 topCapHeight:0];

[doSomethingButton setBackgroundImage:stretchableButtonImagePressed

forState:UIControlStateHighlighted];

}

노트

이 프로젝트에서 사용한 프로젝트 템플릿에서는 viewDidLoad 메서드의 스텁 구현체까지 자

동으로 생성해준다. 하지만 이 메서드는 처음에는 주석 처리돼 있다. 앞의 예제 코드는 스텁

메서드 내에 직접 작성해도 되고 주석 처리된 메서드를 아예 삭제하고 처음부터 다시 메서드

를 작성해도 된다.

이 코드에서는 프로젝트에 추가한 템플릿 이미지를 활용해 버튼의 배경 이미지를 설정한다.

이 메서드에서는 버튼을 터치하는 동안 버튼이 흰 이미지에서 파란색 이미지를 사용하도록 지정

한다. 간단해 보이는 이 메서드에서는 컨트롤의 상태와 확장 가능 이미지라는 두 가지 새로운 개

념이 들어 있다. 이들 개념이 뭔지 차례대로 살펴보자.

Page 140: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

116 l 시작하세요! 아이폰 4 프로그래밍

컨트롤의 상태

모든 iOS 컨트롤에는 네 개의 컨트롤 상태가 있으며 각 컨트롤은 특정 순간에 이들 상태 중 한

상태만을 가질 수 있다.

▶ 일반 상태 : 가장 일반적인 상태는 일반 컨트롤 상태로서, 이 상태는 컨트롤의 기본 상태

다. 이 상태는 컨트롤이 다른 상태에 해당하지 않을 때 컨트롤이 기본으로 갖는 상태다.

▶ 하이라이트 상태 : 하이라이트 상태는 컨트롤이 현재 사용 중일 때의 상태다. 버튼의 경

우 하이라이트 상태는 사용자의 손가락이 버튼 위에 올라온 상태다.

▶ 비활성화 상태 : 인터페이스 빌더에서 Enabled 체크박스를 선택 해제하거나 컨트롤의

enabled 속성값을 NO로 설정해 컨트롤의 기능을 꺼버린 경우 컨트롤은 비활성화 상태

가 된다.

▶ 선택 상태 : 선택 상태는 일부 컨트롤에서만 지원한다. 이 상태는 보통 컨트롤의 기능이

활성화돼 있거나 사용자가 컨트롤을 선택했음을 알리는 용도로 사용한다. 선택 상태는

하이라이트 상태와 비슷하지만 사용자가 더 이상 컨트롤을 직접 사용하지 않는 경우에

도 컨트롤이 선택 상태를 그대로 유지할 수 있다는 점이 다르다.

어떤 iOS 컨트롤은 자신의 상태에 따라 다양한 값을 받을 수 있는 어트리뷰트를 갖고 있다. 예

를 들어 UIControlStateNormal에 대해 이미지를 지정하고 UIControlStateHighlighted에 대해

또 다른 이미지를 지정하면 iOS에서는 버튼에 사용자의 손가락이 올라온 경우에는 한 이미지를

사용하고, 나머지 경우에는 다른 이미지를 사용한다.

확장 가능 이미지

확장 가능 이미지는 재미있는 개념이다. 확장 가능 이미지는 자신의 크기를 어떻게 조절해야 할

지 알고 있는 이미지로서 이미지의 크기를 확장하더라도 올바른 모양을 그대로 유지한다. 버튼

템플릿의 경우 나머지 이미지 영역과 달리 이미지의 모서리 부분이 늘어나면 안 된다. 이미지의

양쪽 끝은 픽셀 단위로 측정하며 리사이즈되서는 안 된다. 모서리 주변의 베벨은 버튼 크기와 상

관없이 형태를 그대로 유지해야 한다. 따라서 여기서는 양쪽 끝의 크기를 12로 지정했다.

여기서는 이미지 템플릿 대신 새로운 확장 가능 이미지를 넘겨줬으므로 iOS에서는 어떤 크기

의 버튼도 제대로 그릴 수 있다. 이제 nib 파일에서 버튼의 크기를 바꾸더라도 버튼이 제대로 그

려질 것이다. 만일 nib 파일에서 버튼 이미지를 바로 지정했다면 전체 이미지의 크기가 모두 변경

되므로 대부분의 버튼 크기에서 버튼 모양이 이상하게 보였을 것이다.

Page 141: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 117

이미지 양쪽 끝의 크기 값을 어떻게 알 수 있었을까? 원리는 간단하다. 그냥 애플의 예제 코드

에서 값을 복사한 것이다.

메모리 관리 모범 시민 되기

새 버튼을 테스트하기 전에 언급할 주제가 한 가지 더 남았다. 버전 3.0 이후 모든 iOS에서

는 UIViewController 클래스에 메모리를 적게 사용할 수 있게 도와주는 메서드가 포함됐다.

UIViewController 클래스는 코코아 터치에서 모든 뷰 컨트롤러가 상속하는 클래스로서 예제

에 사용한 Control_FunViewController 클래스 또한 이 클래스를 상속한다. 새로 추가된 이 메

서드의 이름은 viewDidUnload인데 이 메서드는 메모리 부담을 줄이는 것과 관련해 매우 중요

한 메서드다.

6장에서는 다양한 뷰를 갖고 있는 애플리케이션에 대한 설명을 시작한다. 물론 독자들이 벌써

부터 다양한 뷰를 구현하는 것에 대해 지레 겁을 집어먹기를 바라지는 않는다. 다만 그 전에 뷰

컨트롤러 클래스를 올바로 구현하는 법을 알려주려는 것뿐이다.

여러 뷰가 있는 경우에는 iOS에서 메모리를 보존하기 위해 nib 파일을 로드했다가 언로드한

다. 뷰가 언로드되도 컨트롤러 클래스에서 아웃렛으로 갖고 있는 객체들은 메모리에서 제거되지

않는다. 그 이유는 아웃렛의 속성에서 retain 키워드를 사용해 객체를 보관했기 때문이다. 따라

서 컨트롤러 클래스에서 뷰가 언로드됐다는 것을 알게 되면 메모리에서 아웃렛을 제거할 수 있

게 아웃렛 속성을 nil로 설정하는 게 중요하다. 코코아 터치에서는 nib 파일을 재로드할 때 아웃

렛을 자동으로 재연결하므로 이렇게 하더라도 문제될 소지가 전혀 없다. 이런 접근 방식을 활용

하면 독자들은 불필요한 메모리를 보관하지 않는 메모리 관리 모범 시민이 될 수 있다.

Control Fun 애플리케이션은 단일 뷰 애플리케이션이므로 프로그램 실행 중에는 viewDid

Unload가 호출될 일이 없다. 하지만 애플리케이션이 처음에 단일 뷰 애플리케이션으로 시작했

다고 해서 앞으로도 애플리케이션에 뷰가 하나만 있을 거라고는 장담하기 어렵다. 따라서 꼭 필

요하지 않다는 사실을 분명히 아는 경우에도 메모리 관리 모범 시민이 되기 위한 에티켓을 그대

로 지키는 게 좋다. 뷰가 언로드될 때 아웃렛을 릴리스하도록 Control_FunViewController.m에

서 다음 스텁 함수의 내용을 채우고 메모리 관리 모범 시민으로 거듭나자.

Page 142: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

118 l 시작하세요! 아이폰 4 프로그래밍

- (void)viewDidUnload {

self.nameField = nil;

self.numberField = nil;

self.sliderLabel = nil;

self.leftSwitch = nil;

self.rightSwitch = nil;

self.doSomethingButton = nil;

[super viewDidUnload];

}

이때도 오브젝티브-C 언어의 점 표기법 사용법에 주의하자. 이번에는 대입 명령문의 왼쪽에서

점 연산자를 사용했으므로 점 표기법을 통해 수정자를 호출하고 있다. 예를 들어 다음 코드는

self.nameField = nil;

다음 코드와 같다.

[self setNameField:nil];

이때 수정자가 호출될 때 어떤 일이 일어날지 생각해보자. 앞에서 retain 키워드를 사용해 수

정자를 합성한 것을 기억하자. 수정자에서는 먼저 새로운 객체를 보관하고 과거 객체를 릴리스

한 후 새로운 객체를 인스턴스 변수에 대입한다. 여기서는 수정자에서 nil을 보관하므로 결국 아

무 일도 하지 않게 된다. 이어서 과거 객체를 릴리스하는데, 이 객체가 바로 메모리에서 제거하려

는 객체다. 보관 중이던 과거 객체가 아웃렛에 원래 연결돼 있던 객체이기 때문이다. 끝으로 nil을

nameField에 대입한다.

이 메서드를 추가한 후 파일을 저장하고 애플리케이션을 테스트해 보자. 모든 게 이전과 똑같

이 동작하고 버튼의 모양만 좀 더 아이폰답게 바뀌었을 것이다. viewDidUnload 메서드를 추가

했다고 하더라도 애플리케이션에서 동작이 달라진 점은 찾아볼 수 없다. 하지만 잠자리에 들 때

는 오늘도 착한 일 한 가지를 했다는 생각에 잠이 잘 올 것이다. 작업하느라 모두 수고했다!

결승선 통과하기

이 장의 내용은 꽤 많았다. 이 장에서는 새로운 개념을 많이 소개하진 않았지만 다양한 컨트롤

을 사용하는 법을 보여줬고 다양한 구현 예제에 대한 세부 내용을 살펴봤다. 이 장을 통해 독자

들은 아웃렛과 액션을 수없이 사용해 봤고 뷰의 계층 구조적인 성격을 활용하는 법도 배웠다. 또

Page 143: 시작하세요! 아이폰 4 프로그래밍 : iOS SDK를 이용한 아이폰 개발

04 더 재미있는 사용자 상호작용 l 119

이 장에서는 컨트롤의 상태와 확장 가능한 이미지에 대해서도 배웠고 액션 시트와 경고창을 활

용하는 법도 살펴봤다.

이 장에서 만든 작은 애플리케이션에서는 많은 일이 일어난다. 예제로 돌아가 원하는 형태로

얼마든지 예제를 실험해 보자. 값을 바꿔보고 코드를 추가하거나 수정해 보자. 또 인터페이스 빌

더에서 다른 설정을 적용할 때 어떤 결과가 나오는지도 확인하자. iOS에서 사용할 수 있는 모든

컨트롤의 모든 세부 내용을 독자들에게 일일이 알려주는 것은 불가능하겠지만 이 장에서 방금

만든 애플리케이션은 이에 대한 좋은 시작점으로 활용할 수 있고 꽤 많은 기본 내용을 다루고

있다.

다음 장에서는 사용자가 iOS 기기를 세로 모드에서 가로 모드로 전환하거나 그 반대로 전환

할 때 어떤 일이 일어나는지 살펴본다. 사용자가 기기를 들고 있는 방식에 따라 디스플레이가 바

뀌는 애플리케이션들은 독자들도 지금껏 많이 봤을 것이다. 다음 장에서는 이런 애플리케이션

을 실제로 만드는 법을 설명한다.