오브젝트C2011. 4. 9. 10:46
커널패닉 채널에서 peniar님과 xcode 예기를 하다가 xcode가 gcc를 사용한다는 소리를
듣고서 gcc를 사용한다면 리눅스에서도 obj-c 개발 환경 구성이 가능하지 않을까 싶어
검색해보았습니다.

참고한 사이트 :: [ http://ubuntuforums.org/showthread.php?t=1064045 ]

우분투 리눅스에서는 obj-c 관련 패키지가 gobjc더군요

$sudo apt-get install gobjc

하시게되면 관련 패키지가 여럿 설치가 됩니다.

objc 소스코드를 컴파일 하는 방법은
$gcc -o -Wall 실행파일 소스코드.m -lobjc

편집기로 vim을 사용하시는 분은 .vimrc 파일에 key mapping을 통해서 
vim 내에서 컴파일이 가능하게 할 수 있습니다.

.vimrc 파일 설정
filetype on
au FileType objc map <F2> : !gcc -o -Wall %< % -lobjc
au FileType objc map <F3> : !./%<


이렇게 지정 해두시면 F2를 누르면 컴파일, F3을 누르면 실행이 됩니다.

뭐 이렇게 설정한다고 해도 리눅스에서 아이폰/아이패드 개발이 가능한 것은 아닙니다 
흣 그저 간단히 obj-c 개발이 가능할 뿐이죠 =_=


출처 : http://blog.naver.com/PostView.nhn?blogId=nsjkim&logNo=140115657293
Posted by 오늘마감

댓글을 달아 주세요

-Xcode3.2.3과 SDK4로 업그레이드 후, 기존 앱 업그레이드 하는 법-
XCode3.2.3 과 SDK4로 버전업한 후, 기존 앱을 업그레이드 할 때 간단한 Tip 입니다.
1. XCode3.2.3과 SDK4로 업그레이드 한다. 별도로 기존 XCode 3.1 버전을 따로 보관할 필요가 없습니다.
2. 기존 앱을 새 XCode3.2.3에서 연다.
3.Group & Files를 right click -> Get Info 후
  3-1.General Tab 에서
Project Format 을 Xcode 3.2-compatible 로 바꾼다.
 3-2.Build Tab 에서
 Base SDK를 iPhone Device 4.0(배포시), 혹은 iPhone Simulator 4.0(테스트시) 로 바꾼다
 iPhone OS Deployment Target 을 iPhone OS 3.0 (즉 지원하고자 하는 하위버전으로) 로 바꾼다.


출처 : http://blog.naver.com/PostView.nhn?blogId=megaissue&logNo=140111719543
Posted by 오늘마감

댓글을 달아 주세요


설치된 Xcode를 실행하면 아래와 같은 화면이 뜹니다.

여기에서 Create a new Xcode Project를 클릭하면 다음과 같은 화면이 뜹니다.

 

 

저의 환경에서는 6종류의 Application을 만들 수 있는 Project Template이 있군요.

그럼 이제 6종류의 Templates에 대하여 살펴 보기로 하지요.

 

A) Navigation-based Application

This temple provides a starting point for an application that uses a navigation controller. It provides a iser interface configured with a navigation controller to display a list items.

네비게이션 컨트롤러를 기반으로 하는 어플, 계층 구조로 더 깊은 단계로 들어갔다가 나올 수 있는 형태의 어플을 만들 수 있다.

Navigation-based Application 템플릿은 아래 그림의 타이틀 모양과 같은 네비게이션 바를 표시할 때 사용한다. 주로 타이틀과 좌우에 간단한 버튼을 표기할 때 사용한다.




템플릿을 선택한 다음 자동으로 생성된 코드를 그냥 빌드 해보면 위의 오른쪽 그림과 같은 형태가 나온다.

Xcode 에서 빌드하기

Xcode 에서 빌드는 아래와 같이 상단의 아이콘을 클릭하거나 단축키 +를 ㄹ누르면 된다.





위의 왼쪽 그림과 같이 setting 형태의 버튼과 타이틀을 넣는 방법은 여러 가지가 있다. 먼저 Xcode SDK의 UI 구성툴인 Interface Builder(IB)를 이용하는 방법을 살펴보자. Xcode 에디터에서 코드를 수정하는 것이 조금은 필요하다. 위 그림에서 처럼 소스 브라우저 창에서 MainWindow.xib 라는 파일을 더블 클릭하면 인터페이스 빌더가 실행된다. *.xib 파일은 IB에서 사용하는 UI의 프로젝트 파일에 해당된다. IB는 크게 4개의 메인폼을 가지고 있다. 아래 그림 첫번째는 IB에서 사용된 각종 콘트롤들을 아이콘 형태로 보여주는 View 윈도우이며(아래그림1), 해당 View의 설정을 위한 UI 디자인창이 있다.(아래그림2) 그리고, Attribute를 설정하는 창과(아래그림3) 각종 라이브러리와 오브젝트들을 모아 놓은 Library 창이 있다. 여기서 Navigation Controller를 선택하고, Navigation item Attribute의 'Title' 항목과 'Back Button'항목을 아래 세번째 그림처럼 설정해준다. 여기서 설정한 내용은 실시간으로 UI 디자인창에 반영된다. 단, Back Button은 코드를 수정하면 볼 수 있다.







이렇게 만들어진 내용을 IB에서 'File | Save'메뉴로 저장하고 나와서 다시 빌드하면 'Wi-Fi Networks'라는 타이틀이 보일것이다. 그리고, 'Settings' 라는 아이템을 추가 하려면 RootViewController.m 파일에서 주석처리 되어 있는 함수를 아래와 같이 수정하면 된다. 각각의 프로퍼티를 변경해서 iPhone에서 사용되는 각종 Navigation 버튼을 구현할 수 있다.


- (void)viewDidLoad { 

[super viewDidLoad]; 

self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

}



다음은 Controller란 무엇인가를 알 수 있는 간단한 그림입니다.

 

 

다음은 Navigation Controller가 사용되는 간단한 어플입니다.

 


 

B) OpenGL ES Application

This template provides a starting point for an application that uses an OpenGL ES-baces view. It provides a view into which you render your OpenGL ES scene, and a timer to allow you to animate the view.

게임 등을 게발하기 위해서 3D엔진인 OpenGL ES를 사용할 수 있다. (자세한 것은 다음에 만들어 보면서..)

 iPhone OS는 게임등과 같이 화면 전환이 빠르게 요구되는 어플리케이션들을 위해서 그래픽 라이브러리로 OpenGL ES(Open Graphic Library Embedded System)라는 라이브러리를 기본적으로 지원한다.

OpenGL ES는 Khronos Group(http://www.khronos.org/opengles/)에서

제공하는 Open GL의 임베디드 버전이다. 2D와 3D 데이터를 표현하기 위한 C언어 베이스의 크로스 플랫폼 인터페이스이다. 이 템플릿을 추가하면 기존에 화면(View)을 그리기 위해 사용했던 CoreGraphics.framework 대신에 아래 그림과 같은 2개의 framework이 추가 된다.




역시 아무런 조작이 없이 Xcode 에서 'Build and Run' 버튼으로 동작시켜 보면 아래 그림과 같은 애니메이션 어플리케이션이 실행된다.(박스가 상하로 움직이는 것을 볼 수 있다.)




아래 그림은 Open GL/ES템플릿을 선택했을 경우 프로젝트 화면이다. Navigation 템플릿과달리 여러 가지 리소스들이 포함된 것을 볼 수 있다.





Open GL에 관해서 몇 개의 참조 사이트를 소개하도록 하겠다.

http://developer.apple.com/iphone/library/documentation/3DDrawing/Conceptual/OpenGLES_

ProgrammingGuide/Introduction/Introduction.html

: 이곳은 Apple 에서 공식적으로 제공하는 OpenGL/ES 프로그래밍 가이드를 소개하는 페이지이다. iPhone OS 에서 OpenGL ES를 활용한 프로그램과 프레임 버퍼를 이용하는 방법, Vertex Data, Texture Data 등을 활용하여 만든 예제, 퍼포먼스 가이드라인, Texturetool 을 사용하는 방법들을 설명해 준다.

또한 아래와 같은 사이트를 참조하라고 소개하고 있다. OpenGL ES API Registry(http://www.khronos.org/registry/gles/)

OpenGL ES 2.0 Reference Pages (http://www.khronos.org/opengles/sdk/docs/man/)

OpenGL ES Framework Reference 함수 설명 사이트 (http://developer.apple.com/iphone/library/documentation/OpenGLES/Reference/OpenGLES_

Framework/index.html#//apple_ref/doc/uid/TP40007628

)

iPhone용 OpenGL ES 강좌 사이트(영문; http://web.me.com/smaurice/AppleCoder/iPhone_OpenGL/iPhone_OpenGL.html)

Khoronos group 에서 제공하는 OpenGL ES SDK 메뉴얼 사이트(http://www.khronos.org/opengles/sdk/docs/man/)





C) Tab Bar Application

This template provides a starting point for an application that uses a tabbar. It provides a iser interface configured with a tab bar for the first tab bar item.

Tab Bar를 사용하는 어플을 만드는 곳입니다.

Tab Bar는 Application 뷰의 하단에 위치해서 뷰를 전환하는 역할을 하는 버튼들을 모아놓는 곳이다. Navigation Bar와 유사하다. iPhone OS의 기본프로그램에도 많이 쓰여 지고 있다. 아래 그림은 Tab Bar의 여러 가지 유형의 보여주고 있다.

 





아래 그림은 템플릿을 사용한 프로젝트를 만들고 바로 빌드한 모습니다. 2개의 뷰를 Tab Bar를 사용해서 보여주고 있다.




템플릿을 활용하여 위와 같이 2개의 뷰를 전환하는 예제에서는 각각의 뷰가 필요하다. IB에서 탭이 늘어날 때마다 아래와 같이 Tab Bar Controller Attributes 에서 + 를 클릭한 후 탭과 별도의 뷰를 하나씩 늘려가면 된다.





 


D) Utility Application

This template provides a starting point for a utility application that a main view and a flipside view. It sets up an info button to flip the main view to the flipside, and a navigation bar with a Done item to flip back to the main view.

날씨나 증권같이 위젯 형태의 어플을 만들 수 있는 곳. 단순히 보여주기만 할 뿐, 사용자 입력을 받을 필요가 거의 없는 곳에서 사용하면 적합하다고 하는데 다른 템플보다 이쁘군요.

이 템플릿은 info 버튼이 포함된 Main view와 네비게이션 바를 가진 flipside 형태로 전환되는 뷰를 가진 어플리케이션을 만들때 사용되는 템플릿이다. iPhone 어플리케이션에서 설정 화면등을 구성할 때 자주 사용된다. 아무런 수정도 하지 않고 템플릿을 로드하고 'Build and Run' 했을때 아래와 같은 화면을 볼 수 있다.



이 템플릿은 IB로 디자인하기 위해서 FlipsideView.xib, MainView.xib, MainWindow.xib와 같은 2개의 뷰와 1개의 MainWindow를 가진 리소스를 제공한다. 각각의 View에 해당되는 소스와 ViewController 소스가 템플릿으로 제공되어 진다. 그리고, 이들 뷰간의 동작들을 담당하기 위해서 appDelegate가 역시 템플릿으로 제공된다. (아래 그림참조) 이 템플릿은 MainView에 원하는 Application을 동작시키고 설정 항목등을 FlipsideView에 위치시킬때 사용하면 좋을 것이다.





 

E) View-based Application

This template provides a starting point for an application that uses a single view. It provides a biew controller to manage the view, and a nib file that contains the view.

하나의 뷰가 추가된 어플

이 템플릿은 싱글 뷰를 가진 어플리케이션을 만들 경우 사용되는 템플릿이다. 사실 싱글 뷰로 어플리케이션을 만드는 경우는 거의 없을 것이다. 하지만, 뷰를 조작하기 위한 view controller를 제공해 주고 IB를 위한 간단한 nib 파일을 제공해 준다. 이 템플릿의 장점은 뷰가 많은 Application을 제작할 때 일일이 신경 쓰지 않고도 간단히 원하는 view와 view controller를 가진 UI를 빨리

생성해 주어서 작업능률을 올릴 수 있다는 것이다.






F) Window-based Application

This template provids a starting point for any application. It provides just an application delegate and a window.

가장 기본적인 형태도 뷰도 없다. 따라서 스스로 뷰를 추가하여야 한다.

이 템플릿은 하나의 MainWindow와 AppDelegate 만을 제공해 주는 가장 기본적인 템플릿이다. 개인적으로 IB를 사용하여 UI작업을 할 때 가장 자주 사용하는 템플릿이다. 이 템플릿 위에 뷰와 Object 들을 배치시키고 어플리케이션을 만들 수 있다. 버튼을 누르면 팝업창이 뜨는 간단한 어플리케이션을 예제로 만들어 보겠다.


1) 아래 그림과 같이 MainWindow.xib를 클릭해서 IB를 시작한다.




2) 아래 그림과 같이 IB의 Library 창에서 View Object를 Window 창으로 드래그한다. 그 후에 이 뷰를 메인뷰로 사용할 것이기 때문에 Class명을 myView로 수정한다.






3) 이제 Image View Object와 Round Rect Button Object를 가져와서 그림과 같이 배치한다. Object를 뷰에 올리는 방법은 이전 단계에서 했던 것과 마찬가지로 드래그하면 된다. 그리고, image View Attributes 창에서 aimage.png 라는 그림 파일을 불러온다. 이 그림 파일은 처음에 프로젝트를 만든 후에 Finder로 부터 Project tree로 드래그해서 추가해 놓은 것이다.(필자는 Resources 디렉토리에 두었다.)








4) 이제는 myView에 만들어진 Object들의 IBOutlet을 만들고 event 코드를 작성할 차례이다. IBOutlet은 IB를 사용해서 Object를 포함하는 View를 만들었을 경우 각각의 Object를 control 하기 위해서 만들어 준다.

최종 동작은 '누르세요'라는 버튼을 클릭했을 때 info 베너가 동작하도록 하는 것이다.

IB에서 myView 에 해당되는 소스파일을 프로젝트로 넣기 위해서 저장을 하도록 한다. IB의 메뉴에서 'File | Write Class Files' 를 선택한다. 이 때 myView.h myView.m 파일을 프로젝트에 추가할 것인지를 창이 뜬다. 체크 버튼을 체크해 주고 해당 파일을 프로젝트에 'Add' 해 준다.




5) 프로젝트에 IB에서 만든 UI 소스가 포함되고 나서, 먼저 myView.h 파일의 내용을 아래와 같이 고쳐준다.

#import #import

@interface myView : UIView { IBOutlet UIButton *pBtn; //pBtn을 눌렀을때 showInfo가 동작 IBOutlet UIImage *pImg

} -(IBAction)showInfo;

@end

또, 실제 alert 메시지창을 보여주는 함수 내용은 myView.m에서 작성한다.

#import "myView.h"

@implementation myView -(IBAction)showInfo { UIAlertView *baseAlert = [[UIAlertView alloc] initWithTitle:nil


message:@"showInfo 가 실행되었\n 습니다." delegate:self cancelButtonTitle:nil otherButtonTitles:@"확인",nil];show];release];

}

@end




6) '누르세요' 버튼을 터치다운 했을 경우 showInfo() 라는 함수가 실행되도록 만들기 위해서 IB에서 먼저 해주어야 할일이 있다. 아래 그림처럼 버튼 Object에서 마우스 오른쪽 클릭을 한 후에( 원버튼 마우스의 경우; Ctrl+윈쪽클릭) 'Touch Down' 이벤트를 드래그해서 myView로 가져가면 아래 그림과 같이 showInfo 함수를 선택할 수 있도록 활성화 된다.





7) 이제 저장하고 Xcode에서 빌드하면 showInfo()가 아래 그림과 같이 동작하게 된다. 이런식으로 각각의 Object 들과 터치 이벤트등을 연결할 수 있다.







이상으로 6개의 Project Template를 살펴보았습니다.

그럼 자신이 만들고자 하는 어플과 가장 유사한 템플릿을 선택하여 프로젝트를 시작하면 되겠지요!



출처 : http://blog.naver.com/PostView.nhn?blogId=jforyoum&logNo=60117746694
Posted by 오늘마감

댓글을 달아 주세요

iOS와 멀티미디어 프로그래밍

지난 2월, 많은 사람들이 관심을 갖고 있는 아이패드2와 iOS 4.3 버전, Xcode 4 등이 발표됐다. 특히 아이패드2의 경우 다른 애플 제품들이 발표됐을 때처럼 스티브잡스가 제품을 직접 들고 나와서 훌륭한 프리젠테이션으로 소개하기도 했다. 이번에도 역시 제품 출시 전 여러 가지 루머들이 있었지만 이들 소문이 무색할 정도로 뛰어난 사양의 제품이었다.

안경훈 linuxgood@gmail.com | 리눅스와 맥OS에 관심이 많으며, 모바일 디바이스에서 동작되는 사용자 중심의 프로그램을 개발하는 것에 흥미를 갖고 있다. 현재 삼성SDS에서 근무 중이다.

iOS에서 오디오와 비디오를 활용한 멀티미디어 프로그램을 작성하는 방법을 알아보자. 일반적으로 iOS에서 사용되는 오디오/비디오 리소스들은 멀티미디어 프레임워크를 사용해 프로그램 된다. 이를 통해 다음과 같은 기능들이 포함된 애플리케이션을 만들 수 있다.

- 오디오 레코딩과 플레이, 스트리밍 데이터를 활용한 AV 플레이
- 게임 등에 등장하는 간단한 사운드 플레이
- 실시간 음성 녹음
- 아이패드 라이브러리에서의 사운드 플레이
- 비디오 플레이와 레코딩의 지원
- 간단한 비디오 플레이와 레코딩의 지원

오디오 기능 사용
iOS 4.0이 나올 무렵 아이폰4와 아이패드 등의 보급이 활성화됐다. iOS에서 사용되는 오디오 프레임워크의 사용법을 살펴보자.
멀티미디어 데이터를 재생하기 위해 사용되는 프레임워크로는 다음과 같은 것들이 있다.

● MediaPlayer.framework
음악, 오디오 북, 오디오 팟 캐스트 등과 같은 리소스들을 플레이하기 위해 사용된다.

● AVFoundation.framework
간단히 음악을 플레이하거나 녹음을 할 때 사용되는 프레임워크로서 AVAnimation이나 캡처된 아이템 등을 플레이할 때도 자주 사용된다.

● AudioToolbox.framework
패킷을 통해 전달되는 오디오나 오디오 포맷을 변경할 때, 오디오 큐를 활용해 오디오 데이터 등을 변경할 때 사용된다.

● AudioUnit.framework
컴포넌트 입력이나 출력을 위해 오디오 데이터를 가공할 때 사용된다.

● OpenAL.framework
게임이나 특별한 목적으로 사용되는 오디오 데이터를 가공할 때 사용된다. iOS는 현재 OpenAL 1.1(http://openal.org/) 버전을 지원한다.

오디오 프레임워크 사용
오디오 프레임워크를 사용하기 위해서는 다른 프레임워크를 사용할 때와 마찬가지로 #import! 명령으로 해당 프레임워크를 코드에 포함하면 된다. 다음과 같은 형식으로 코드에 포함한다.
#import! <AVFoundation/AVFoundation.h>

iOS에서 지원되는 오디오 코덱
이제 iOS에서 지원되는 오디오 코덱을 살펴보자.

● 플레이를 위한 코덱
오디오 데이터와 같은 것이 iOS에서 사용될 때에는 기본적으로 압축을 하게 되는데 이러한 압축을 실시간으로 해제해 소리가 나도록 하는 것이 코덱이다. iOS에서 코덱을 사용해 플레이 될 수 있는 오디오 포맷에는 <표 1>과 같은 것들이 있다. 일반적으로 자주 사용되는 코덱은 모두 지원한다고 생각하면 된다. <표 1>에서 볼 수 있는 하드웨어 코덱과 소프트웨어 코덱들은 동시에 같은 타입의 디코딩을 지원할 수는 없다. 즉, 하드웨어로 오디오 데이터들을 디코딩하는 중에 다른 오디오 소스를 디코딩해야 할 일이 생기면 소프트웨어 코덱을 사용해야 한다는 말이다. 반대로 소프트웨어 코덱을 사용해 디코딩할 때도 마찬가지다.

<표 1> 지원되는 하드웨어, 소프트웨어 코덱

<표 2> 녹음을 위한 하드웨어, 소프트웨어 코덱

● 녹음을 위한 코덱
iOS에서 지원되는 녹음을 위한 오디오 포맷에는 <표 2>와 같은 것들이 있다. 하드웨어를 사용한 녹음은 AAC 타입으로만 사용될 수 있다. 다른 타입으로 녹음하려면 소프트웨어를 기반으로 인코딩해야 한다.

환경에 따른 오디오 세션의 활용
오디오가 플레이 될 경우 우리는 여러 가지 예외 상황을 맞을 때가 있다. 오디오를 순간적으로 음소거(Mute)시키거나 사용자가 정지시켰을 때, 헤드폰 잭을 꽂았을 경우와 뺀 경우, 스크린 락을 걸었을 때, 시계의 알람을 울릴 때 등 각종 오디오를 재시작했을 경우에 오디오를 조절하는 API들이 있는데 이것을 오디오 세션 API라고 한다. 오디오 세션 API 중 중요한 클래스들을 살펴보자. 

<화면 1>과 같이 디자인된 애플리케이션이 있다. (http:// developer.apple.com/library/ios/#samplecode/avTouch/Listings/Classes_avTouchController_mm.html)에서 가져온 ‘avTouch’라는 샘플코드로 AVAudioSession 클래스를 사용하는 좋은 예제다.

<화면 1> avTouchController 프로그램

<화면 1>에서 보는 바와 같이 각각의 기능들이 동작하면서 오디오 세션의 조절 기능을 하게 된다. sample.m4a라는 오디오 파일을 사용자의 조작에 의해 플레이하는 역할이다. 사용되는 오브젝트들을 중심으로 알아보자.

1.  다음과 같은 헤더 파일을 불러온다.

<UIKit/UIKit.h>
<AudioToolbox/AudioToolbox.h>
<AVFoundation/AVFoundation.h>

2. 오디오 플레이를 위한 델리게이트를 추가하고 각종 버튼들을 위한 코드를 추가한다. 추가돼야 할 것은 AVAudioPlayer Delegate와 다음에 열거된 오브젝트들이다. 각각의 버튼 이름들이 화면에서 보이는 기능을 의미한다.

...
IBOutlet UIButton *playButton
IBOutlet UIButton *ffwButton
IBOutlet UIButton *rewButton
IBOutlet UISlider *volumeSlider
IBOutlet UISlider *progressBar
IBOutlet UILabel *currentTime
IBOutlet UILabel *duration
...
AVAudioPlayer *player
UIImage *playBtnBG
UIImage *pauseBtnBG
NSTimer *updateTimer
NSTimer *rewTimer
NSTimer *ffwTimer
...

음악이 연주되면서 LevelMeter 등의 애니메이션이 동작하게 되는데 그 자세한 설명을 생략하겠다(시뮬레이터에서는 레벨메터 애니메이션이 동작하지 않을 수도 있다). 또한 재생을 멈췄다가 다시 플레이 할 경우에 사용되는 타이머도 있다(NSTimer).

3.  플레이와 앞으로 가기, 볼륨 슬라이더 등에 대한 액션을 처리하기 위해 다음의 함수들을 만든다. 앞으로 감거나 뒤로 감는 동작을 위해 각각의 버튼들에 대해 press와 release 함수를 만들었다. 볼륨 슬라이드와 프로그래스 바를 위한 함수도 있다. 백그라운드로 동작하거나 포그라운드로 동작할 때의 동작을 등록하기 위해 Notification 함수도 만든다.

(IBAction)playButtonPressed:(UIButton*)sender;
(IBAction)rewButtonPressed:(UIButton*)sender;
(IBAction)rewButtonReleased:(UIButton*)sender;
(IBAction)ffwButtonPressed:(UIButton*)sender;
(IBAction)ffwButtonReleased:(UIButton*)sender;
(IBAction)volumeSliderMoved:(UISlider*)sender;
(IBAction)progressSliderMoved:(UISlider*)sender;

(void)registerForBackgroundNotifications;

4. 각 함수에 해당되는 동작에 관한 코드를 작성한다. 플레이 버튼이 눌렸을 경우 AVAudioPlayer의 객체인 player의 playing 플래그를 사용해 현재 오디오가 플레이 중인지의 여부를 판단, 플레이 중이라면 pausePalybackForPlayer라는 함수를 동작시켜 오디오 플레이를 임시로 중단시키고 플레이 중이 아니라면 startPlaybackForPlayer라는 함수로 계속 소리가 나도록 한다. 각각의 함수가 동작할 때 버튼 이미지나 현재 상황을 업데이트 해 주며 업데이트를 위한 타이머가 작동한다(updateCurrentTimeForPlayer).

<리스트 1> 오디오 플레이 버튼 입력 함수

- (IBAction)playButtonPressed:(UIButton *)sender
{
   if (player.playing == YES)
      [self pausePlaybackForPlayer: player];
   else
      [self startPlaybackForPlayer: player];
}


오디오 볼륨을 위해 볼륨 슬라이드를 움직일 경우 UISlider로부터 전달된 player 객체의 볼륨 조절 함수가 동작해 볼륨값이 조절된다.

<리스트 2> 볼륨 슬라이더 조작 함수

- (IBAction)volumeSliderMoved:(UISlider *)sender
{
   player.volume = [sender value];
}


오디오가 재생되는 도중에 슬라이드 바를 움직일 경우 해당되는 지점으로 이동하는 동작이 필요하다. 이 때 사용되는 것이 progressSliderMoved 함수다.

<리스트 3> 프로그래스 바 조작 함수

- (IBAction)progressSliderMoved:(UISlider *)sender
{
   player.currentTime = sender.value;
   [self updateCurrentTimeForPlayer:player];
}


뒤로 감기 버튼이나 전진 버튼을 눌렀을 경우(Pressed)와 놓았을 경우(Released)에는 <리스트 4>와 같은 함수들이 사용된다. 실제로 동작할 때는 NSTimer를 사용해 스킵 간격을 조절하게 된다.

<리스트 4> 앞/뒤 감기 버튼 함수

- (IBAction)rewButtonPressed:(UIButton *)sender
{
   if (rewTimer) [rewTimer invalidate];
   rewTimer = [NSTimer scheduledTimerWithTimeInterval:SKIP_INTERVAL target:self selector:@selector(rewind) userInfo:player repeats:YES];
}

(IBAction)rewButtonReleased:(UIButton *)sender
{
   if (rewTimer) [rewTimer invalidate];
   rewTimer = nil;
}


오디오가 재생되는 중에 화면보호 기능 등이 동작하거나 사용자가 임의로 버튼을 눌렀더라도 지속적으로 오디오가 나와야 할 경우가 있을 것이다. 이를 위해 애플리케이션이 초기화되는 부분에서 AVAudioSessionCategoryPlayback을 사용, <리스트 5>와 같은 코드를 작성해 준다. 

<리스트 5> 오디오 세션의 지속적 플레이 함수

NSError *setCategoryErr = nil;
NSError *activationErr = nil;

[[AVAudioSession sharedInstance]
setCategory : AVAudioSessionCategoryPlayback
error: &setCategoryErr];
[[AVAudioSession sharedInstance]
setActive: YES
error : &activationErr];


다음으로 전화가 오거나 알람 설정 등으로 인해 발생되는 인터럽트 처리 방법을 알아보자.
오디오 재생 중에 발생되는 여러 가지 인터럽트들은 <표 3>과 같은 기술들로 처리된다.

<표 3> 오디오 기술과 인터럽트 처리 방식

AAC 타입을 위한 하드웨어 인코딩 방법
앞에서 오디오를 재생하고 녹음을 하는 동안 하드웨어의 인터럽트를 사용한 인코딩/디코딩 방식이 있다고 설명했다. 아이폰의 여러 가지 오프라인 모드에서도(알람이나 전화가 왔을 경우 벨소리) 별도로 오디오를 동작시키는 방법이 필요하다. 이러한 경우 주로 사용되는 오디오 포맷이 AAC인데 코덱을 이용할 수 있는 장치로는 아이폰 3GS 이상의 모델, 아이팟 2세대 이상, 아이패드 등이 있다. AudioConverterRef라는 메소드를 활용하면 오디오 변환을 위한 기능들을 사용할 수 있다. 오디오 변환과 관련된 서비스들에 대해서는 ‘Audio Converter Services Reference and Extended Audio File Services Reference’라는 문서를 참조하면 된다. 

오디오 재생이나 녹음이 진행될 때 인터럽트가 발생됐을 경우의 라이프 사이클은 <그림 1>과 같이 설명할 수 있다. 진행되는 순서에 따라 살펴보자.

<그림 1> 오디오 재생시 앱의 라이프사이클(출처 AudioSessionProgrammngGuide.pdf)

1. 애플리케이션의 오디오를 동작시킨다.
2. 전화가 와서 인터럽트가 걸린다. 폰 애플리케이션의 오디오 세션이 활성화된다.
3. 이 때 시스템이 사용자의 오디오 세션을 비활성화 시킨다.
4. 시스템이 사용자의 인터럽트 리스너 콜백 함수를 invoke시키거나 인터럽트가 시작됐다는 델리게이트 메소드를 호출한다. 사용중이던 애플리케이션은 잠시 비활성화 된다.
5. 사용자의 콜백 또는 델리게이트 메소드는 액션에 해당되는 동작을 하게 된다.
6. 만약 사용자가 인터럽트를 무시하는 동작을 하면(전화를 받지 않거나 할 경우) 시스템은 인터럽트가 끝났다고 간주하고 다음 동작을 할 것이다.
7. 사용자의 콜백 또는 델리게이트 메소드는 인터럽트 종료시 동작된다. 예를 들면 사용자 인터페이스를 업데이트하거나 오디오 재생 등을 다시 시작할 경우 쓸 수 있다.

오디오 세션을 위한 팁들
이제 오디오 세션을 동작시키기 위한 코드들을 살펴보면서 실제 예를 통해 어떤 방식으로 활용할 수 있을지 알아보자.

● 오디오 세션의 초기화
오디오 인터럽트를 위한 AV 델리게이트 등을 사용하려고 한다면 오디오 세션을 초기화 한 상태에서 가능할 것이다. 오디오 인터럽트와 연관된 여러 가지 함수들을 잘 사용하기 위해 AudioSessionInitialize라는 함수를 호출해야 한다. 이것은 애플리케이션이 시작될 때 한 번만 불리도록 만들면 된다. 애플리케이션에서 오디오 세션의 초기화 등을 하지 않았을 경우에는 iOS에서 기본으로 제공하는 싱글톤 오디오 세션 오브젝트가 로딩이 끝난 후에 사용할 수 있도록 제공된다. 함수는 <리스트 6>과 같이 제공되며 Audioservice.h에 정의돼 있다.

<리스트 6> 오디오 세션 초기화 함수
AudioSessionInitialize(CFRunLoopRef inRunLoop,
                     CFStringRef inRunLoopMode,
                     AudioSessionInterruptionListener inInterruptionListener,
                     void *inClientData
   );


첫 번째 인자는 main 함수의 loop를 위해 사용된다. 두 번째 인자는 main이 아닌 run loop 모드에서 사용된다. 세 번째 인자는 리스너 콜백 함수에 해당되며 <리스트 7>과 같이 정의돼 있다.

<리스트 7> 오디오세션 인터럽트 리스너 콜백 함수

typedef void (*AudioSessionInterruptionListener)(
                               void *  inClientData,
                               UInt32  inInterruptionState
   );


각종 인터럽트는 다음과 같은 장치들을 연결하거나 동작시키는 상황에서 발생된다.

“Headset” “Headphone” “Speaker” “SpeakerAndMicrophone” “HeadphonesAndMicrophone” “HeadsetInOut” “ReceiverAnd Microphone” “Lineout”

네 번째는 사용자 데이터로 정의돼 있는데 오디오 세션 오브젝트가 invoke됐을 때 사용자의 인터럽트 리스너 콜백 함수로 연결시키도록 만들어져 있다(간단히 말하면 사용자가 의도한 함수를 실행하게 만든다).

● 사용자 오디오 세션의 활성화/비활성화
AVFoundation framework를 활용해 오디오 세션을 활성화 할 경우의 코드를 보자.

NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];

이 경우 비활성화 할 때는 setActive 속성을 “NO”로 변경해 주면 된다. 다음과 같은 스타일로 오디오 세션을 활성화/비활성화 할 수도 있다.

OSStatus activationResult = NULL;
result = AudioSessionSetActive (true);

● 애플리케이션이 시작될 때 다른 오디오가 재생되고 있는지 확인
사용자가 애플리케이션을 시작할 때 이미 오디오 장치를 통해 소리가 나고 있다면 어떻게 할지에 대해 생각해 보자. 이런 경우는 주로 게임을 시작할 때 등에 해당될텐데 게임을 시작하기 전에 오디오 세션이 잘 초기화돼 있는지 등을 살펴보고 다음 동작으로 이어진다.

<리스트 8> 오디오 세션 체크 함수

UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof (otherAudioIsPlaying); AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying);

if (otherAudioIsPlaying) { [[AVAudioSession sharedInstance]
   setCategory: AVAudioSessionCategoryAmbient error: nil];
}
else { [[AVAudioSession sharedInstance]
   etCategory: AVAudioSessionCategorySoloAmbient error: nil];
}


오디오가 플레이되고 있는지의 여부를 판단하는 프로퍼티 ID에는 AudioServices.h에 다음과 같이 enum 값이 정의돼 있다. 이 값이 otherAudioIsPlaying 변수에 할당된다.

kAudioSessionProperty_OtherAudioIsPlaying = ‘othr’,
// UInt32(get only)

또한 AVAudioSession.h에는 <리스트 9>와 같이 정의돼 있다.

<리스트 9> 오디오 세션 플레이 체크 상수

extern NSString *const AVAudioSessionCategoryAmbient;     // 다른 오디오가 재생되고 있을  경우
extern NSString *const AVAudioSessionCategorySoloAmbient;   // 재생되고 있지 않을 경우


● 재생 중 믹싱 동작
두 가지 오디오 소스로부터 입력을 받아 믹싱한 후에 재생할 필요가 있을 경우에는 특별히 <리스트 10>과 같이 동작을 설정할 수 있다. 이 예는 Voicemail.caf 파일과 음악 파일을 동시에 재생할 경우 어떻게 처리하는지에 대해 설명한다.

<리스트 10> 오디오 믹싱과 재생 함수

AudioSessionInitialize( NULL, NULL, NULL, NULL );  
// 오디오 세션 초기화
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
AudioSessionSetProprty(true);   //오디오 세션의 프로퍼티를 동작으로 설정한다. 이 경우 음악 등을 재생하고 있으면 계속 소리가 나오는 상태가 된다.

NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:@"Voicemail"
ofType:@"caf"]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
[audioPlayer play];   // 믹서의 동작으로 Voicemail.caf 파일을 재생하게 된다.


현재 오디오의 동작 상태를 결정하는 AudioSessionSetActive 함수는 AudioServices.h에 다음과 같이 정의돼 있다.

extern OSStatus AudioSessionSetActive(Boolean active);  

이제 코드를 통해 애플리케이션에서 사용되는 사운드 재생법을 살펴보자(연재를 작성하는 중에 Xcode 4 버전이 발표돼 화면들은 새로운 버전을 기준으로 작성됐다).

1. View-based Application 프로젝트를 생성한다. 프로젝트의 이름은 AudioSample01로 만들었다(Xcode 4는 프로젝트의 이름을 정하면서 자체적으로 메소드 등에 대해 Unit Test를 할 수 있는 옵션을 제공한다).

<화면 2> View based template 선택

<화면 3> 프로젝트 이름 설정

<화면 4>와 같이 프로젝트가 생성됐다.

<화면 4> 프로젝트 정보 화면

2.  이번 예제에서는 화면 구성을 위해 Interface Builder를 사용했다. <화면 5>와 같이 재생중인 오디오 파일의 이름이 나오게 될 라벨과 오디오 재생 이벤트를 설정할 <확인> 버튼을 위치시켰다(Xcode 4에서는 인터페이스 빌더도 하나의 윈도우에 나타나도록 디자인됐다).

<화면 5> 인터페이스 빌더 화면

3. 오디오를 재생하게 될 <확인> 버튼과 오디오 파일의 정보를 표시할 라벨에 대해‘AudioSample01ViewController.h’에 <리스트 11>과 같이 코드를 작성한다.
    그리고 AudioToolbox.frame work을 추가한다.

<리스트 11> 버튼과 라벨 설정

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}


4. PlaySound라는 함수에 오디오 파일명을 <리스트 12>와 같이 입력한다. SystemSoundID라는 타입을 정의해 AudioServices CreateSystemSoundID, AudioServicesPlaySystemSound라는 형식으로 플레이하게 된다. 화면에서 <확인> 버튼을 누르면 type.wav 파일이 재생되면서 파일명이 라벨에 표시된다.
<리스트 12> 오디오 재생 함수

-(IBAction)PlaySound:(id)sender
{
   NSString *path = [[NSBundle mainBundle] pathForResource:@"type" ofType:@"wav"];
   SystemSoundID soundID;
   label.text = path;
      
   NSLog(@"path is %@", path); //null print on iphone
      
   AudioServicesCreateSystemSoundID((CFURLRef) [NSURL fileURLWithPath:path], &soundID);
   AudioServicesPlaySystemSound(soundID);
}

Xcode 4에 프레임워크 추가

기존에는 프로젝트 내비게이션 트리에서 오른 쪽 클릭으로 프레임워크를 추가할 수 있었다. 새로운 버전에서는 <화면 6>과 같이 프로젝트 메뉴를 선택하고 TARGETS 항목의 Build Project 영역을 선택해 Link Binary With Libraries라는 곳에서 ‘+’를 선택함으로써 프레임워크를 추가하면 된다. 프로젝트에서 사용되는 여러 가지 프로파일들을 한 곳에 모아두기 위한 방법이라고 생각된다.

<화면 6> 프레임워크 추가 화면


아이폰 시뮬레이터

아이폰이나 아이패드 개발 뿐만 아니라 임베디드 디바이스의 애플리케이션을 개발할 때는 테스트를 위해 소스 코드를 빌드한 후에 이미지를 실제 장비에 설치하게 된다. 하지만 간단한 UI나 디자인 등을 테스트하기 위해 실제 장비에 매번 이미지를 설치하는 작업은 시간이 필요 이상으로 많이 걸리는 일이다. 이럴 경우 임베디드 환경에서는 보통 시뮬레이터라고 하는 소프트웨어적인 가상의 장치를 사용하게 된다. 

아이폰에서 사용되는 시뮬레이터는 <화면 7>과 같은 형태인데 재미있는 기능이 있다. 아이폰(아이패드)에는 모바일 키노트 애플리케이션이나 동영상 애플리케이션의 화면을 TV 화면으로 보낼 수 있는 기능이 있다. ‘iOS Simulator’에도 이같은 기능이 있다. ‘Hardware’ 메뉴에 ‘TV Out’ 항목이 그것으로, 해상도별로 세 가지 모드를 시뮬레이션해 준다.

<화면 7> iOS 시뮬레이터

유튜브 화면을 플레이해 봤다. 시뮬레이터는 <화면 8>과 같은 화면으로 변경되고 <화면 9>와 같은 TV Out 화면이 나타난다.

<화면 8> 동영상 플레이 화면

<화면 9> TV Out 화면


참고자료

1. MultimediaProgrammingGuide.pdf
https://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/Introduction/Introduction.html%23//apple_ref/doc/uid/TP40009767
2. https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/ GS_AudioVideo_iPhone/




출처 : http://blog.daum.net/_blog/hdn/ArticleContentsView.do?blogid=05JzW&articleno=16056926&looping=0&longOpen=
Posted by 오늘마감

댓글을 달아 주세요

다양한 애플리케이션을 사용하는데 있어서 중요한 요소중의 하나는 어떠한 정보를 입력하느냐이다. 특히 스마트폰 같이 작은 크기 때문에 키보드 같은 물리적 입력도구를 갖지 못하는 경우에는 더욱 더 신중하게 다루어야 하는 요소이다. 아이폰에서는 몇가지 종류의 키보드를 제공하고 있다. 영어, 한글, 숫자, 특수문자등의 필요에 따라 원하는 키보드를 호출하여 사용이 가능하다.



New Project.
새로운 프로젝트를 시작한다. 'View-based Application' 을 선택하고 프로젝트 이름은 'keyBoard' 로 하였다. 이번에 만들게 될 애플리케이션에는 이미지와 여러개의 라벨, 키보드로 입력이 가능한 텍스트 필드 몇개가 있는 프로젝트이다. 여기서 설명하는데로 따라해도 괜찮지만, 각자 새로운 형태의 구성을 해보는 것도 괜찮다.


그림1. 애플리케이션 구상

그림과 같이 각 영역을 구분지어보고, 각 영역별로 어떤 기능을 담당하게 할 것인가에 대해서 생각해 보아야 한다. 처음에 있는 이미지 영역은 단순히 이미지를 나타내기만 한다. 오른쪽의 텍스트 영역 역시 별다른 수정이나 변화가 필요하지 않다. 이제 아래에 있는 영역들을 보면, 'Name : ' 와 'Anumber : ' 는  텍스트필드 영역에 어떤 내용이 들어가야 하는지에 대해서 설명을 해주기 때문에 별 다른 변화가 필요하지 않다. 오른쪽 아래의 텍스트 필드 영역은 실제적으로 이름과, 군번(Anumber) 가 들어가는 자리이다. 이 영역에는 뭔가 입력을 받고, 데이터를 저장하는 등의 상호작용을 위한 부분이 되는 것이다. 이렇게 구성을 확인해 보면, 아웃렛이나, 액션이 선언되어야 하는 부분이 확실해 질것이다.


아웃렛 선언하기.
아웃렛을 선언해야 하는 부분은 두개의 텍스트 필드 영역이다. 아웃렛을 선언하기 위해서는 뷰컨트롤러.h 파일에 @property를 선언하고, 뷰컨트롤러.m 파일에 @synthesize 를 선언해 주면 된다.


그림2. keyBoardViewController.h 파일 수정

아웃렛을 선언하려는 부분의 프로퍼티를 선언한다. 프로퍼티를 선언하는 것은 다음과 같이 형식을 취하여 선언하면 된다. (굵은 글씨의 부분을 추가)

@interface keyBoardViewController : UIViewController {
    UITextField *nameField;
    UITextField *AnumberField;
}
@property (nonatomic, retain) IBOutlet UITextField *nameField;
@property (nonatomic, retain) IBOutlet UITextField *AnumberField;
@end



그림3. keyBoardViewController.m 파일 수정

헤더파일에 아웃렛을 선언한 후에 뷰컨트롤.m 파일에 @synthesize 선언자를 통해 선언을 해 주어야 접근자 메소드와, 변경자 메소드가 생성된다.

@implementation keyBoardViewController
@synthesize nameField;
@synthesize AnumberField;


또한, 메모리에 관련한 부분도 잊어서는 안된다. 아이폰 처럼 매우 적은 메모리를 사용하는 기기일 수록 메모리가 낭비되는 일이 없도록 꼼꼼하게 프로그래밍을 해야 한다. retain 키워드를 사용해 선언한 변수들을 모두 release 해주어야 한다.

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



이미지 추가하기.
아이폰 프로그래밍에서 이미지를 사용하기 위해서는 'Groups&Files' 창의 'Resource' 폴더에 포함되어 있어야 한다. 아이폰에서 보여주고자 하는 작은 크기의 이미지로 작업을 해야 아이폰에서 이미지 크기를 변경하는 불필요한 연산을 줄일 수 있다. 사용하고자 하는 파일을 파인더에서 'Resource' 폴더로 끌로와서 포함을 시키거나, 'Resources' 폴더의 우클릭 메뉴에서 'Add' -> 'Existing Files...'을 해서 이미지 파일을 추가할 수 있다.


그림4. 이미지 파일 추가.


화면 디자인 하기.
'Resources' 폴더의 'keyBoardViewController.xib' 파일을 더블클릭하여 인터페이스 빌더를 실행한다. 먼저 이미지를 추가하기 위해서는 라이브러리 윈도우에서 'Image View' 를 드래그 해서 View 윈도우에 놓아야 한다.


그림5. 이미지 뷰 추가.

위의 화면과 같이 꽉 찬 화면의 이미지뷰가 뷰 윈도우에서 선택되어 진 것을 볼 수 있을 것이다. 하지만 우리가 넣고자 하는 이미지는 아직 들어가 있지 않다. 이미지뷰는 이미지의 영역을 구분하는 경계정도로 생각하면 된다.


그림6. 실제 이미지 표현

실제로 이미지가 나타나게 하기 위해서는 Attribute 윈도우의 'Image' 에 이미지 파일을 추가해 주어야 한다. 드롭다운 선택 메뉴가 나오는데, 여기에는 'Resource' 폴더에 포함된 이미지들만 나오게 된다. 여기서 원하는 이미지를 선택하면 위의 그림과 같이 이미지가 뷰에 표현되는 것을 볼 수가 있다. 간혹 실제 이미지를 표현하기 전에 이미지 영역이 뷰 영역의 뒤로 표현이 되서 선택을 못하는 경우가 발생하는데, 이럴 경우에는 main 윈도우의 View Mode 를 리스트 보기로 바꾸면 뷰영역안에 포함되어 있는 목록을 볼 수 있다. 여기에서 이미지 뷰 영역을 선택하면 뷰 윈도우에서도 똑같이 선택할 수 있다.


그림7. main 윈도우 리스트로 보기

이미지를 이미지 뷰 위에 올려놓은 후에는 이미지와, 이미지뷰의 크기를 똑같이 하는 작없이 필요하다. 이는 자원의 낭비를 줄이는 것도 되겠지만, 이미지 뷰 영역 자체가 하나의 영역으로 작용하기 때문에, 다른 영역과 겹칠 수 있는 가능성을 없애고, 이미지 외 별도의 효과를 주는 것을 피하기 위해서이다. 이미지 영역을 맞추기 위해서는 '사과키' + '=' 을 누르거나 메뉴에서 'Layout' -> 'Size to Fit' 을 선택하면 된다. 이미지에 대한 작업을 마치고, 라벨을 적당한 위치에 배치하고, 내용을 변경하여 구상했던 모양대로 인터페이스를 구성한다.


그림8. 라벨, 텍스트필드 인터페이스 디자인

이미지와 라벨, 텍스트 영역을 이리저리 움직이다보면 나타나는 가이드 라인을 이용하면 어색하지 않은 인터페이스를 구성할 수 있을 것이다. 각 라이브러리 별 인스펙터도 하나하나 변경해보며 어떤 기능들이 있는지 확인해 보는 것도 재밌는 경험이 될 것이다. 텍스트 필드의 애트리뷰트 중에서는 사용자의 입력의 편의를 위해서 몇가지 주의를 해야 할 항목들이 있다. 먼저 'Clear When Editing Begins' 의 체크박스는 사용자가 텍스트 필드를 선택할때 기존에 있던 내용을 지우고 새로 시작할 것인지를 설정하게 된다. 체크를 해 놓으면 기존의 있던 내용이 텍스트 필드를 선택할 때마다 지워지고, 체크를 해제하면 기존의 내요이 유지가 된다. 보통은 체크를 해제하여 사용하도록 한다. 'Adjust to Fit' 체크박스는 입력하고자 하는 내용이 텍스트 필드의 크기보다 커질 경우 글씨의 크기가 줄어드는데, 줄어드는 정도의 최소 크기를 정하는 것이다. 체크를 해 놓으면 정해진 만큼 이하로는 글씨의 크기가 작아지지 않는다. Keyboard 메뉴는 입력하고자 하는 내용에 맞는 적절한 키보드가 나타나도록 한다. Name 필드 같이 이름을 입력할 경우에는 텍스트로 되어 있기 때문에 일반적인 키보드를 불러내도 상관없지만, Anumber 필드 같이 숫자만 입력하는 필드 같은 경우는 문자대신 숫자로만 이루어진 키보드가 적절하다. 이럴땐 팝업 메뉴에서 'Number Pad' 를 선택하면 숫자로만 이루어진 키보드가 나타나게 된다.


아웃렛 연결하기.
인터페이스를 완성하였다면 아웃렛을 연결해 주어야 한다. main 윈도우의 'File's Owner' 아이콘에서 'ctrl' 키를 누른채 아웃렛이 선언되어 있는 텍스트필드로 끌어주면 아래와 같은 팝업메뉴가 나오고, 텍스트필드에 맞게 선택해 주면 된다.


그림9. 아웃렛 연결

아웃렛을 연결하는 작업까지 마무리 지었다면 모든 과정이 일단은 마무리 되었다. 빌드를 하고 실행을 해보고 멋들어진 애플리케이션의 모습을 보도록 하자.


그림10. 애플리케이션 시뮬레이터.

그림과 글씨가 보이고 뭔가 있어보이는 듯한 애플리케이션을 완성하였다. 텍스트 필드를 클릭하면 텍스트와 숫자를 입력할 수 있는 키보드도 나타나게 된다. 하지만... 뭔가 생각지 못했던 문제가 있다.


키보드 사라지게 하기.
텍스트 필드에 문자를 입력하고난 후 키보드가 사라지지 않는 것이다. 입력을 마쳐도 마쳤다는 신호를 보낼 수가 없다. 어떻게 사라지게 할 수 있을까? 상식적으로 생각을 해보면 된다. 우리가 모든 입력을 마친후 마침을 의미하는 'return' 키를 입력하게 되는데, 아이폰에서도 'return' 키를 입력하였을때 키보드가 사라지도록 만들면 된다. 키보드 화면에서 'return' 키를 입력하게 되면 'did end on exit' 이벤트가 생성되는데 이 이벤트가 발생함과 동시에 텍스트 필드에 대한 입력이 더이상 이루어지지 않도록 하면 된다. 컨트롤러에 액션 메소드를 추가하려면 'keyBoardViewController.h' 파일에 다음의 코드를 추가해 넣으면 된다.

@interface keyBoardViewController : UIViewController {
    UITextField *nameField;
    UITextField *AnumberField;
}
@property (nonatomic, retain) IBOutlet UITextField *nameField;
@property (nonatomic, retain) IBOutlet UITextField *AnumberField;
- (IBAction) textEndReturn: (id)sender;
@end


그리고 'keyBoardViewController.m' 파일에 '(IBAction)' 액션 메소드를 구현하는 코드를 추가한다.

@implementation keyBoardViewController
@synthesize nameField;
@synthesize AnumberField;

- (IBAction) textEndReturn: (id)sender {
    [sender resignFirstResponder];

}


메소드를 구현하는 코드는 특별히 정해진 위치는 없기 때문에 적당한 위치에 입력하도록 한다. 이 메소드는 퍼스트 리스폰더의 상태에서 물러나게 된다. 텍스트를 입력하기 위해 텍스트 필트를 선택하면 텍스트 필드가 현재 실행하고 상호작용하고 있는 컨트롤을 의미하는 '퍼스트 리스폰더'의 상태를 가지게 된다. 그리고 동시에 텍스트를 입력할 수 있는 키보드가 나타나게 된다. 이때 키보드의 'return' 키를 눌러 퍼스트리스폰더 상태에서 물러나게 되는 액션이 실행되면, 더이상 텍스트 필드를 선택한 상태에 머무르지 않게 되는 것이다.


키보드 사라지는 액션 연결하기.
액션을 정의한 후에는 실제적으로 작동을 할 수 있도록 인터페이스 빌더에서 연결을 해 주어야 한다.


그림11. 액션 연결.

액션을 연결하고자 하는 텍스트 필드를 선택하고 'TextField Connections' 윈도우를 보이도록 한다. 텍스트 필드의 키보드에서 'return' 키를 누르면 액션이 반응하도록 할 것이기 때문에 'Did End On Exit' 액션을 이용하도록 한다. 'Did End On Exit' 의 오른쪽 부분의 원에 커서를 가져가면 십자가 모양으로 바뀌는 것을 볼 수 있다. 이것을 끌어다가 main 윈도우의 'File's Owner' 아이콘으로 가져가면 Xcode 에서 퍼스트리스폰더를 포기하는 액션이 정의된 메소드의 이름이 나타나는 것을 볼 수 있다. 이것을 선택하여 액션이 연결되도록 한다.


'return' 키가 없는 숫자패드 사라지게 하기.
일반적인 키보드에는 'return' 키가 포함되어 있어서 입력이 완료되었음을 알려줄 수 있다. 하지만, 숫자로만 이루어진 키패드에는 숫자와 삭제버튼만 있을 뿐이다. 이런 키보드를 사라지게 하기 위해서는 어떻게 해야 할까? 이것 역시 간단하다. 키보드가 아닌 다른 곳을 터치할때 키보드가 사라지게 만들면 된다. 키보드가 아닌 다른곳을 터치할때는 어떤 컨트롤러에 액션을 연결해 주어야 할는걸까? 답은 뷰 컨트롤러에 연결하면 된다. 하지만, 라이브러리를 아무리 찾아보아도 뷰 컨트롤러는 찾을 수가 없다. 하지만, 찾지 않아도 된다. 이미 뷰 컨트롤러는 UIview 안에 포함되어 있기 때문이다. 프로젝트를 생성하면 기본적으로 만들어지는 view 는 여러 뷰 라이브러리를 담아두는 컨테이너의 역할을 한다. 모든 라이브러리가 UIview 의 하위클래스라는 것이다. 또 UIcontrol 역시 UIview 의 하위클래스이기 때문에 view는 control 의 역할까지 가질 수 있는 것이다.


그림12. view 클래스 변경

main 윈도우에서 view 아이콘을 선택하고, 'Control Identity' 윈도우를 띄운다. 위의 그림과 같이 class identity 를 변결할 수 있는 메뉴가 나오는데 view 의 클래스를 UIcontrol 로 변경하도록 한다. 이제 '뷰' 에도 액션을 추가할 수 있게 되었다. 배경을 터치하여 키보드가 사라지는 액션을 추가하는 방법은 이전의 방법과 동일하다. 먼저 'keyBoardViewController.h' 파일에 액션을 선언하는 코드를 추가한다.

- (IBAction) textEndReturn: (id)sender;
- (IBAction) backgroundTap: (id)sender;
@end


그리 고 'keyBoardViewController.m' 파일에 '(IBAction)' 액션 메소드를 구현하는 코드를 추가한다.

- (IBAction) backgroundTap: (id)sender {
    [nameField resignFirstResponder];

    [AnumberField resignFirstResponder];
}


위의 액션이 실행되면 nameField 와 AnumerField 객체가 가지고 있는 퍼스트 리스폰더를 모두 포기하게 된다. 만약 위에 있는 '[nameField resignFirstResponder];' 를 주석처리 한다면 AnumberField 만 퍼스트 리스폰더를 포기하게 되므로, AnumberField 에서만 액션이 작용하는것과 같은 결과가 나타나게 된다.


숫자패드 사라지는 액션 연결하기.
모든 코딩을 마무리 하였다면, 인터페이스 빌더로 이동하여 액션들을 이어주는 작업을 하도록 한다.


그림13. UIcontrol 액션 연결하기.

main 윈도우에서 Control 아이콘을 선택하고 'Control Connections' 윈도우를 띄운다. 이 'Control' 아이콘은 화면의 가장 배경을 나타내는 View 와 같은 것이라고 할 수 있다. View는 화면 전 영역을 나타내기 때문에 버튼에서 사용했던 'Touch up Inside' 액션이 아닌 'Touch Down' 액션을 사용하도록 한다. 'Touch Down' 의 오른쪽에 있는 원으로 커서를 이동시켜 십자가 모양으로 변경되면 이것을 끌어다가 main 윈도우의 File's Owner 아이콘으로 가져다 놓는다. 팝업 메뉴로 나오는 액션 메소드중 배경을 클릭하여 키보드를 사라지게하는 메소드인 'backgroundTap' 메소드를 선택한다. 지금까지의 작업들을 저장하고 Xcode로 돌아가 빌드하고 실행해보도록 한다. 텍스트필드에 키보드를 통하여 입력이 가능하고, 'return' 버튼을 누르거나 배경을 클릭하면 키보드가 사라지는 것을 볼 수 있을 것이다. 좀더 자세한 상호작용이 가능해진 것이다!




출처 : http://blog.daum.net/_blog/hdn/ArticleContentsView.do?blogid=0LU4x&articleno=5216143&looping=0&longOpen=
Posted by 오늘마감

댓글을 달아 주세요