NHN다니시는 변해준씨 (36)가 개발한 Heavy Mach가 2주만에 게임 다운로드 3위로 등극하셨다네요.
10만 다운로드로 약 1억 4천만원의 수익을 얻게 되셨다는데 대단하네요 ^^



그런데 일전에 이런 기사를 봤는데요.

한국, 앱스토어 게임 사전 심의하는 유일한 국가

 게임을 서비스하려면 게임물등급위원회에 등급심사를 받아야한다는 것을 지인으로부터 듣게 됐다. 
그는 게임위에 전화를 걸어 게임등급을 받는 방법을 묻다가 등급을 받으려면 사업자등록증이 필요하다는 말에 힘없이 전화기를 내려놨다. 
자신이 다니던 회사는 잡쉐어링을 인정하지 않는 회사였기 때문에 게임을 개발하려면 직장을 그만 두어야할 상황이었던 것이다. 

으흠... 그럼 NHN 은 잡쉐어링을 인정한다는 말인가요 아니면, 한국 앱스토어에 올리지 않고 외국에 올린건지..
좀더 알아봐야 겠군요 ^^;

방금 맥부기 카페에서 물어봤는데, 외국에 올리면 문제 없다는 답변을 받았네요 ^^... ㅎㅎ


어쨋든 대단하다는 생각도 들고, 열심히 저도 만들어봐야 겠다는 생각이 드네요.

모두 모두 화이팅!



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



iPhone에서 간단한 겜을 만들까 검색했더니 기존 Cocoa Obj-C 버전의 Cocos2d 게임라이브러리를 iPhone용으로 공개했네요.

다음에서 라이브러리를 다운 받아볼 수 있습니다.
Cocos2d game library homepage

라이센스 문제?
일단 Cocos2d for iPhone은 기존의 LGPL을 따른다고 하네요. 소스 공개해야겠죠? 
그런데 이런 문구가 있더군요.
이곳에 말이죠?

cocos2d for iPhone license:
---------------------------

cocos2d for iPhone was originally licensed under the GNU LGPL v3 license.
But since it is impossible to distribute 3rd party dynamic libraries
for the iPhone, this license extends the GNU LGPL v3 license by allowing you: 
  a) to use cocos2d for iPhone as a static library
  b) to include all or part of the cocos2d for iPhone sources inside your project

This means that if you do a) and/or b) you are NOT forced to release your 
source code under the GNU LGPL v3 license.

즉, 기본적으로는 LGPL v3이긴 한데 3rd party 동적 라이브러리로 배포하기 어렵기 때문에, 정적 라이브러리 식으로 사용하거나, 프로젝트에 그냥 소스의 일부 또는 전부를 포함하여 컴파일하면 LGPL의 규제를 벗어날 수 있다고 하네요.

엡스토어에 올려도 될까?
또 찾아보던 중 다음과 같은 글들이 있더군요.

Cocos2d accepted by apple?!

They've already allowed games using it on the app store Chuck the Ball and Sophos Tongue are both cocos2d.
이미 엡스토어 Chuck the Ball과 Sophos Tongue라는 게임이 올라와 있네요.

한 술 더 떠서 아래 링크에는 위 라이브러리를 사용하여 올린 게임들이 있다고 하네요.
http://code.google.com/p/cocos2d-iphone/wiki/GamesUsingCocos2d


그럼 어떤걸 만들 수 있을까?

다음은 홈페이지에서 자랑하고 있는 기능 목록입니다.

Main features


그렇군요. 꽤 되는거 같네요. ㅋㅋ
다음은 간단한 기능 목록 유투브 입니다.


뭔가 좋은 기능을 많이 제공 하네요.

시작하려면 튜토리얼이 필요해

아래 사이트는 간단한 튜토리얼 입니다.
http://monoclestudios.com/cocos2d_whitepaper.html

그리고 몇가지 팁이 있는 블로그도 있네요.

http://blog.sapusmedia.com/search/label/cocos2d

스켈릭톤 코드도 있군요!
http://groups.google.com/group/cocos2d-iphone-discuss/web/sample-games

실행해 보면 간단한 게임이 나옵니다. (게임이긴 한건가... ㄷㄷㄷ; )
그냥 마우스 클릭하면 그쪽으로 움직이고 공으로 가면 끝..;


그래도 게임의 메뉴와 이정도의 스켈릭톤 코드면 뭐든 만들 수 있을거 같네요.
그런데 이 소스는 약간 예전 버전의 cocos2d버전을 사용한 거 같네요.
현재 버전 0.7 으로 포팅하는데 약간 손이 갑니다.. 다음 포스팅 때 얘기를 할까 합니다.

일단 현재 버전의 데모를 돌려보도록 하죠.

백문이불여일행

Cocos2d for iPhone을 아래 사이트에서 다운로드 받습니다.
현재 버전은 0.7이네요.

맥은 똑똑해서 다운받은 tar.gz 더블클릭하면 그냥 내용이 보입니다.

폴더에서 xcode프로젝트 파일을 더블클릭합니다.

엄청 많이 있네요.
TestCocos2는 제가 만든겁니다; 무시..;;
일단 test2 그룹을 제외하면 라이브러리 관련 그룹이라고 보시면 됩니다.
중요한 것은 Targets라는 현재 프로젝트를 설정하는 것인데요.

메뉴에 Project/Set Active Target과 Set Active Executable을 원하는 놈으로 설정합니다.

그리고 당연히 무조건 애플키 + R 을 하면 Compile & Debug Run이 됩니다.
만일 안되면 일단 라이브러리가 생성안되서 그런걸 수 있으니 cocos2d 를 target으로 하고 컴파일 해주세요. 그럼 .a 라이브러리 생깁니다.
만일 네트웍 기능 쓰는 데모면 cocosLive라이브러리 target설정 후 컴파일해야하고 물리엔진 쓰면 Chipmunk라이브러리도 미리 컴파일해서 마련해야 합니다. 


YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



파일 입출력 테스트 함수

먼저 파일 시스템에 파일을 쓰고 읽으려면 당연하겠지만, 파일을 하나 생성해 놔야 합니다. (NSFileManager::createFilePath를 활용)
그렇지만 만일 실행파일 내의 리소스 안의 파일에 대해 (리소스 번들) 읽고 쓰려면 파일 생성을 해놓는것이 아니라, xib가 있는 Resource 노드에 파일 하나를 생성해 놓으면 되지요. (이에 대해선 아래에 다시 그림으로 설명하겠습니다 ^^)

아래 예제는 각 애플리케이션 마다 존재하는 다큐먼트 디렉터리에 파일을 하나 생성하고, 그 파일에 대해서 쓰고 읽는 예제입니다.
재미있는 점은 파일  I/O 는 NSData를 사용해야 한다는 점이다. 따라서 NSString을 NSData로 서로 변환하는 것을 볼 수 있습니다.

마지막으로 생성된 파일의 위치는 iPhone Simulator에서 실행했을 때와 실제 Device에서 실행했을 때 각각 다릅니다. 아래 주석으로 그 패스를 설명해놓았으니, 실행해 보신 후 해당 패스를 가보시면 파일이 만들어져 있는것을 확인해 볼 수 있습니다.

- (void) TestFile_ReadWrite {

/////////////////////////////////////////////////////////////////////////////

// 파일 시스템의 디렉터리 파일 준비

/*

Document Directory Full Path

--------------------------

iPhone Simulator : /Users/kyungmincho/Library/Application Support/iPhone Simulator/User/Applications/7AE9E3F3-3347-4B73-BA73-DCF6A9AFA57B/Documents/

Actual Device : /var/mobile/Applications/7AE9E3F3-3347-4B73-BA73-DCF6A9AFA57B/Documents/

*/

   

// Get documents directory

NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(

  NSDocumentDirectory,

  NSUserDomainMask,

  YES);

NSString* docDir = [arrayPaths objectAtIndex:0];


NSString *filePath = [docDir stringByAppendingString:@"/test.txt"];


// 먼저 파일을 생성한다.

[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];


/////////////////////////////////////////////////////////////////////////////

// 리소스 안에 하려면 Workspace Resources에서 AddFile/Mac OSX/Empty file 추가함.

// 실행 파일 리소스에 있는 파일을 열어서 수정하고자 하면 아래 패스 사용

    //NSString *filePath = [NSString stringWithFormat: @"%@/test.txt", [[NSBundle mainBundle] resourcePath]];


NSLog(filePath);

// 파일에 기록할 내용을 마련한다.

NSString* sText = [NSString stringWithFormat: @"Hello world modified"];

NSUInteger nLen = [sText length];

// NSFileHandle 사용하는 파일 저장용 데이터 타입은 NSData이다

NSData* pData = [sText dataUsingEncoding:NSUTF8StringEncoding];

////////////////////////////////////////////////////////////////////////

// 파일 쓰기 테스트

// 파일을 연다.

    NSFileHandle *hFile = [NSFileHandle fileHandleForWritingAtPath:filePath];

if ( hFile == nil )

{

NSLog(@"no file to write");

return ;

}

// 파일을 쓰고 파일 포인터를 전진하고 파일을 닫는다.

[hFile writeData:pData];

    [hFile truncateFileAtOffset:nLen];

    [hFile closeFile];

////////////////////////////////////////////////////////////////////////

// 파일 쓰기 테스트

// 파일을 연다.

    NSFileHandle *hFile2 = [NSFileHandle fileHandleForReadingAtPath:filePath];

if ( hFile2 == nil )

{

NSLog(@"no file to read");

return ;

}

// 파일을 읽고 파일을 닫는다.

    NSData* pData2 = [hFile2 readDataOfLength:nLen];

    [hFile2 closeFile];

// NSData 화면에 출력할 있는 NSString 타입을 변환한다.

NSString* sReadString = [[NSString alloc] initWithData:pData2 encoding:NSUTF8StringEncoding];

// 디버그 콘솔에 내용을 출력한다.

NSLog(sReadString);

}


만일 리소스 내 파일에 대해서 하고 싶다며
만일 리소스 번들 파일로 만드려면 아래처럼 리소스 안에 파일을 하나 생성해 두면 됩니다.

그리고는 위에 주석을 달아놨던 코드 부분 아래 부분을 주석을 풀어주고 살짝 수정해주면 되겠네요.

/////////////////////////////////////////////////////////////////////////////

// 리소스 안에 하려면 Workspace Resources에서 AddFile/Mac OSX/Empty file 추가함.

// 실행 파일  리소스에 있는 파일을 열어서 수정하고자 하면 아래 패스 사용

    //NSString *filePath = [NSString stringWithFormat: @"%@/test.txt", [[NSBundle mainBundle] resourcePath]];


YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. rooney 2009.07.19 16:52 신고  댓글주소  수정/삭제  댓글쓰기

    유용한 정보 감사합니다. ^^

  2. zenajung 2010.05.25 18:54 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다.
    많은 도움이 되었습니다

  3. BlogIcon repair iphone 2011.06.14 18:38 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다. 제가 이글 퍼가도 되죠?



먼저 TabBarItem의 Image는 30x30의 크기이며 이미지 크기가 안맞으면 자동으로 확대된다.
중요한 점은 이미지의 색깔 정보 (Opaque)는 무시되며 다만 이미지에 포함된 Alpha (투명색) 정보로만 
TabBarItem의 이미지로 설정된다. 선택되었을 때 아닐 때에 맞춰서 그냥 알아서 만들어 준다.

이는 TabBarItem의 Inspector창의 Identifier를 바꾸어보면 예제로 System TabBarItem을 봐도 예로 알수있다.

만일 그냥 일반 이미지 그림을 넣으면 Alpha가 없기 때문에 그냥 네모낳게 나오게 된다.


위 Contact 그림도 보면 색깔은 없고 Alpha정보에 의해서 단색의 이미지가 도출되어있다.


먼저 TabBarItem의 이미지를 설정하기 위해서는 Alpha정보를 설정할 수 있는 이미지 편집 툴이 필요하다.
(마치 윈도우 VC 의 비트맵 에디터 처럼 투명 색을 칠할 수 있는.. )

아쉽게도 -_- 나에겐 그나마 그림툴이라고 PaintBrush 그림판이 있는데 이는 알파를 지원하지 못한다.;
따라서 그냥 Xcode내 Example에서 Alpha 값이 포함된 이미지를 하나 줍어 왔다. 


잘 보면 정사각형 주변이 투명색이다. 따라서 이를 탭바아이템에 넣으면 색이 있는 부분이 단색으로 표현될것이다.

이 파일을 데스크탑이나 탐색기(?)에서 드래그 드럽을 해서 Xcode의 리소스 노드에 가져다 놓는다.


MainWindow.xib를 더블클릭한 후 TabBarItem 첫번째 First를 잘 클릭한 후 Tools/Inspector를 연 후 아래 처럼 Image를 선택한다.
그러면 알파값을 통해 이미지가 들어난다.


이제 Xcode에서 cmd + R으로 실행해 본다

컨택트를 클릭하면 First의 모양은 회색으로 변한다.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


뷰간의 애니메이션 전환을 위해서는 아래와 같은 방식을 해야 한다.

View transition

If you want to change the appearance of a view during a transition—for example, flip from one view to another—then use a container view, an instance ofUIView, as follows:

  1. Begin an animation block.

  2. Set the transition on the container view.

  3. Remove the subview from the container view.

  4. Add the new subview to the container view.

  5. Commit the animation block.


중요한 것은 두 view 간의 전환을 담당하는 컨테이너 뷰 (부모 뷰?)를 두어야 하는 것이다.
( 그렇게 하지 않고 뷰1번이 뷰2번 전환을 담당하게 만들면 애니메이션이 안되고 그냥 확 바뀐다. ; )


프로젝트는 Window based로 생성한다.


1. FirstViewController, SecondViewController 마련하기

File/ New Files로 간 후
Cocoa touch class 중
UIViewController subclass로 FirstViewController를 생성
UIViewController subclass로 SecondViewController를 생성

File/ New Files에서
User interface 중
View XIB로 FirstView로 생성
View XIB로 SecondView를 생성


2. FirstView, SecondView Xib 설정하기
 
FirstView.xib를 더블 클릭하여 Interface Builder를 띄운 후
FirstView.xib의 File's owner를 선택한 후 Tools/ Inspector를 연다.
인스펙터의 4번째 탭의 Class identifier를 선택한 후 FirstViewController를 선택한다.


그리고 File's Owner를 오른클릭한 후 View를 First.xib안의 View로 드래그 드럽으로 연결한다.

그리고 마지막으로 Label을 이용하여 First를 붙인다.

이를 마찬가지로 Second.xib에 대해서도 동일하게 적용한다.


3. RootViewController 마련하기

File/ New Files로 간 후
Cocoa touch class 중
UIViewController subclass로 RootViewController를 생성

RootViewController.h

#import <UIKit/UIKit.h>



@interface RootViewController : UIViewController {

IBOutlet UIButton *button1;

}


- (IBAction) OnFlipView;


@end



RootViewController.m

#import "RootViewController.h"


#import "FirstViewController.h"

#import "SecondViewController.h"


// 간편하게 하기 위해 두 뷰 컨트롤러 포인터를 전역 변수로 마련하였다.


FirstViewController* g_FirstViewController = nil;

SecondViewController* g_SecondViewController = nil;



@implementation RootViewController


...


// Implement viewDidLoad to do additional setup after loading the view.

- (void)viewDidLoad {

    [super viewDidLoad];


// 두 뷰 컨트롤러를 생성한다.

// Xib의 이름을 넣는다. (이때 대소문자 맞춰야한다. xib를 FIrstView로 해서;; 아래처럼 소스를 짰다. )


g_FirstViewController = [[FirstViewController alloc] initWithNibName:@"FIrstView" bundle:nil];

g_SecondViewController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];



// RootViewController의 뷰에 자식 뷰로 g_FirstViewConroller의 뷰를 추가한다. 이 때 button1 자식뷰와 FirstView는 형제 뷰이지만 button1 자식뷰가 firstview보다 앞에 나오게 되어 보이게 된다. (ms윈도우의 z-order과 동일 개념)

// 버튼도 뷰다. UIButton의 클래스 상속을 올라가보면 UIView에서 시작하고 있다.



[self.view insertSubview:g_FirstViewController.view belowSubview:button1];

}



...


// 루트 뷰의 버튼을 누르면 동작되는 뷰전환 함수


- (IBAction) OnFlipView 

{

    UIViewController *from;

UIViewController *to;



// 루트 뷰 자식(sub) 뷰로 firstview 또는 secondview 중 둘 중 하나만 달라 붙도록 코딩되어 있다.

// 만일 g_FirstViewController.view의 부모뷰(superview)가 있다면 현재 firstview가 붙어 있으므로 firstview에서 secondview로 전환되도록 한다.



if( g_FirstViewController.view.superview != nil )

{

from = g_FirstViewController;

to = g_SecondViewController;

}

else

{

from = g_SecondViewController;

to = g_FirstViewController;

}



// 애니메이션 블럭 시작

    [UIView beginAnimations:nil context:NULL];

    [UIView setAnimationDuration:1];

    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];


[to viewWillAppear:YES];

    [from viewWillDisappear:YES];



// 이전 뷰를 부모 뷰(rootview)에서 떼어낸다.

[from.view removeFromSuperview];

// 루트 뷰에다가 전환될 뷰를 추가한다.

[self.view addSubview:to.view];

// 전환될 뷰의 위치는 루트 뷰에 있는 button1과 형제 뷰로써 존재하지만 버튼 보단 뒤에 있게 된다.

[self.view insertSubview:to.view belowSubview:button1];

[from viewDidDisappear:YES];

[to viewDidAppear:YES];


    [UIView commitAnimations];

}


@end




루트 뷰를 메인 윈도우에 추가하기 위해서 다음 처럼 한다.
AppDelegate에 IBOutlet으로 추가해야 나중에 MainWindow.xib의  File's Owner에 root가 보이게 된다.

FlipViewAppDelegate.h

#import <UIKit/UIKit.h>


@class RootViewController;



@interface FlipViewAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

IBOutlet RootViewController* root;

}


@property (nonatomic, retain) IBOutlet UIWindow *window;


@end


FlipViewAppDelegate.m

#import "FlipViewAppDelegate.h"

#import "RootViewController.h"


@implementation FlipViewAppDelegate


@synthesize window;



- (void)applicationDidFinishLaunching:(UIApplication *)application {    


    // Override point for customization after application launch

     // main window에 자식 뷰로 root뷰를 추가한다.

[window addSubview: [root view]];

    [window makeKeyAndVisible];

}



- (void)dealloc {

[root release];

    [window release];

    [super dealloc];

}



@end



RootView를 위해서는 따로 xib를 만들지 않고 그냥 MainWindow.xib안에 추가하도록 하겠다.

먼저 라이브러리에서 ViewController를 MainWindow.xib에 추가한다.



그리고 View Controller를 선태한 후 Tools/ Inspector에서 네번째 탭의 Class 를 RootViewController로 선택한다.
그리고 버튼도 하나 가져다 놓는다.


Root View Controller를 오른클릭하여 버튼과 Outlet 연결을 한다.
버튼은 button1과 연결
OnFlipView도 버튼과 연결한 후 Touch Down과 연결한다.


마지막으로 Flip View App...를 오른클릭 한 후 root를 Root View Controller로 연결한다.



4. 실행하기

cmd + R를 하여 실행하여 버튼을 누르면 First View에서 Second 뷰로, 또 버튼 누르면 Second에서 First로 계속 바뀌게 된다.




정리

- 뷰들 간에는 자식 뷰, 부모 뷰 이렇게 계층을 나눌 수 있다. 
- 뷰들은 투명하다. 즉 부모 뷰와 자식뷰가 있고 자식뷰가 부모 뷰 전체를 덮고 있더라도
  부모 뷰의 컨트롤 (여기 예제에서는 버튼)과 자식 뷰의 컨트롤 (여기 예에선 라벨)이 동시에 보이게 된다.
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. mark 2009.08.23 11:35 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사드립니다~



1. 프로젝트 생성

프로젝트를 Navigation based로 만든다.


2. 에디트 뷰 생성

New File/ Cocoa Touch class중 UIViewController subclass를 선택한 후 ItemViewController로 생성
New File/ User Interfaces 중 XIB View를 선택한 후 ItemView로 생성

3. 에디트 뷰 소스

ItemViewController는 이 뷰에 붙은 TextField의 처리를 위임(delegate)받아서 처리하도록 한다.
여기에서는 에디트 창을 누르면 가상 키보드가 뜨는데 글을 다쓰고 엔터를 누르면 이를 처리하기 위해서 쓰이고 있다.
이를 위해서  UIViewController<UITextFieldDelegate> 이렇게 델리게이트 프로토콜로 받는다.

ItemViewController.h

@interface ItemViewController : UIViewController<UITextFieldDelegate> {

UITableView *tableView;


IBOutlet UITextField *NameText;

NSMutableString *sName;

}


@property (nonatomic,retain) NSMutableString *sName;

@property (nonatomic, retain) UITextField *NameText;

@property (nonatomic, retain) UITableView *tableView;


@end


엔터를 눌러서 값이 변경되면 이를 UITableView에 반영하기 위해서 reloadData를 호출한다.

ItemViewController.m

@implementation ItemViewController


@synthesize sName;

@synthesize NameText;

@synthesize tableView;

 :


- (void)viewDidLoad {

[super viewDidLoad];

NameText.text = sName;

}


- (BOOL)textFieldShouldReturn:(UITextField *)theTextField

{

if (theTextField == NameText)

{

[NameText resignFirstResponder];

[sName setString: NameText.text];

[tableView reloadData];

}

return YES;

}

 :


4. 에디트 뷰 아울렛 연결

먼저 아래 처럼 ItemView.xib를 더블클릭한 후 File's Owner를 선택하고 Tools/ Inspector 창의 네번째 탭의 Class를
ItemViewController로 설정한다.


그리고 Inspector의 두번째 탭의 아울렛 연결 부에서 view와 UITextField를 연결한다.
(물론 File's Onwer를 오른클릭 하여 마찬가지로 드래그 드럽으로 아울렛을 연결해도 된다)


이제 중요한 UITextField를 선택한 후 Inspector의 두번쨰 탭에서 delegate를 File's Owner로 정한다.
(물론 에디트 컨트롤 오른클릭으로 해도 가능)



이것으로 아이템 뷰 쪽은 다 한것이다.

5. UITableViewController 소스

먼저 배열 요소가 변경가능하게 하기 위해서 테이블 리스트 뷰의 데이터로 NSMutableArray를 사용하였다.
그리고 NSMutableString을 요소로 사용하게 되었다.

RootViewController.m

#import "RootViewController.h"

#import "TestTableEditAppDelegate.h"


#import "ItemViewController.h"


// table view 리스트에 표현되는 데이터 배열

NSMutableArray *arr;


@implementation RootViewController

:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [arr count];

}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *CellIdentifier = @"Cell";

    

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    }

    

    // Set up the cell

cell.text = [arr objectAtIndex: indexPath.row];

    return cell;

}


- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath

{ // 마지막 아이템은 + 모양의 추가 모양을 만듬

    if(indexPath.row == [arr count]-1) {

        return UITableViewCellEditingStyleInsert;

    } else {

        return UITableViewCellEditingStyleDelete;

    }

}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


  // deselect the new row using animation

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

// get the element that is represented by the selected row.

NSMutableString *sName = [arr objectAtIndex:indexPath.row];

// create an AtomicElementViewController. This controller will display the full size tile for the element

ItemViewController *controller = [[ItemViewController alloc] initWithNibName:@"ItemView" bundle:nil];

// set the element for the controller

controller.sName = sName;

controller.tableView = tableView;

// push the element view controller onto the navigation stack to display it

[[self navigationController] pushViewController:controller animated:YES];

[controller release];


 }



- (void)viewDidLoad {

    [super viewDidLoad];

    // Uncomment the following line to add the Edit button to the navigation bar.

self.navigationItem.rightBarButtonItem = self.editButtonItem;

arr = [[NSMutableArray alloc] init];

[arr addObject: [[NSMutableString alloc] initWithFormat:@"one"]];

[arr addObject: [[NSMutableString alloc] initWithFormat:@"two"]];

[arr addObject: [[NSMutableString alloc] initWithFormat:@"three"]];

}



// Override to support editing the list

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        // Delete the row from the data source

[arr removeObjectAtIndex: indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

    }   

    if (editingStyle == UITableViewCellEditingStyleInsert) {

        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

[arr addObject: [[NSMutableString alloc] initWithFormat:@"It's new"]];

[tableView reloadData];

    }   

}


// Override to support rearranging the list

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {


[arr exchangeObjectAtIndex: fromIndexPath.row withObjectAtIndex: toIndexPath.row];

}


:


6. 실행하기

실행하면 아래와 같이 나온다.


에디트 버튼을 눌러 에디트 모드로 가보자.



먼저 아이템을 추가하는 기능은 이번에는 마지막 아이템의 에디트 모드 아이콘을 +로 설정하게 하고

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath

// 마지막 아이템은 + 모양의 추가 모양을 만듬

    if(indexPath.row == [arr count]-1) {

        return UITableViewCellEditingStyleInsert;

    } else {

        return UITableViewCellEditingStyleDelete;

    }

}


에디트 버튼을 누르고 + 버튼을 누르면 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        // Delete the row from the data source

[arr removeObjectAtIndex: indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

    }   

    if (editingStyle == UITableViewCellEditingStyleInsert) {

        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

[arr addObject: [[NSMutableString allocinitWithFormat:@"It's new"]];

[tableView reloadData];

    }   

}


위의 코드가 실행되어서 데이터 배열에 It's New가 추가되고 테이블 뷰를 갱신하여 추가된 것이 보이게 된다.



이제 다시 Done을 눌러서 기본 리스트 뷰로 돌아간다.




이제 Two를 눌러보자.  아이템이 선택되면 아래 코드가 실행되어서 ItemViewController가 생성되고 UITableView에 stacking된다

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


  // deselect the new row using animation

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

// get the element that is represented by the selected row.

NSMutableString *sName = [arr objectAtIndex:indexPath.row];

// create an AtomicElementViewController. This controller will display the full size tile for the element

ItemViewController *controller = [[ItemViewController alloc] initWithNibName:@"ItemView" bundle:nil];

// set the element for the controller

controller.sName = sName;

controller.tableView = tableView;

// push the element view controller onto the navigation stack to display it

[[self navigationController] pushViewController:controller animated:YES];

[controller release];


 }


그러면 아이템 뷰가 뜨게된다.


텍스트 필드를 눌러서 가상 키보드가 나오면 대충 값을 바꾼다.



return을 눌러서 값이 NSMutableArray의 한 요소인 NSMutableString 포인터인 sName이 가리키는 배열 요소 실제 값에 setString으로 값을 바꾼다.
그리고 UITableView를 다시 데이터를 로드하도록 한다.

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField

{

NSLog(@"textFieldShouldReturn:");

if (theTextField == NameText)

{

// 텍스트필드의 입력상태(firstResponder) 포기(resign)시킨다. 입력을 상태를 중단시키므로 텍스트 입력 키보드를 해지한다.

[NameText resignFirstResponder];

[sName setString: NameText.text];

[tableView reloadData];

}

return YES;

}


Back버튼을 누르면 수정된 아이템 이 보이게 된다.


예제로는 보이진 않았지만 저번 튜토리얼과 마찬가지로 rearrage가 가능하다. (아이템 이동이 가능하다. )
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


1. 프로젝트 생성

프로젝트를 Navigation based로 생성한다.



2. 소스 변경

RootViewController.m


#import "RootViewController.h"

#import "TestTableImageAppDelegate.h"


// table view 리스트에 표현되는 데이터 배열

NSMutableArray *arr;

UIImage *img1; // 아이템의 아이콘 용 그림



@implementation RootViewController


:

// 제일 마지막 아이템은 새 아이템 추가용으로 사용된다.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [arr count] + 1;

}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *CellIdentifier = @"Cell";

    

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    }

    

    // Set up the cell

if( [arr count] == indexPath.row )

{ // 마지막 아이템은 새로운 아이템으로 사용

cell.text = @"New Item...";

}

else

{

cell.text = [arr objectAtIndex: indexPath.row];

cell.image = img1;

}

return cell;

}


// 리스트 아이템 그릴때 마다 호출되어서 에디트 모드 시 삭제 용인지 추가 용인지 결정

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath

{ // 마지막 아이템은 + 모양의 추가 모양을 만듬

    if(indexPath.row == [arr count]) {

        return UITableViewCellEditingStyleInsert;

    } else {

        return UITableViewCellEditingStyleDelete;

    }

}



- (void)viewDidLoad {

    [super viewDidLoad];

    // Uncomment the following line to add the Edit button to the navigation bar.

self.navigationItem.rightBarButtonItem = self.editButtonItem;

arr = [[NSMutableArray alloc] initWithObjects: @"one", @"two", @"three", nil];

img1 = [UIImage imageNamed: @"img1.png"];

}


// Override to support editing the list

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        // Delete the row from the data source

[arr removeObjectAtIndex: indexPath.row];

        

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

    }   

    if (editingStyle == UITableViewCellEditingStyleInsert) {

        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

// 아이템을 배열 마지막에 추가한 후 테이블 다시 그리기

[arr addObject: @"It's new"];

[tableView reloadData];

    }   

}



// Override to support rearranging the list

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {

int toRow;

if( toIndexPath.row == [arr count] )

// fix bug

toRow = [arr count]-1;

else

toRow = toIndexPath.row;


[arr exchangeObjectAtIndex: fromIndexPath.row withObjectAtIndex: toRow];

}


// Override to support conditional rearranging of the list

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {

    // Return NO if you do not want the item to be re-orderable.

// 마지막은 이동 불가 = 모양 안나타남

if( [arr count] == indexPath.row )

return NO;

return YES;

}





3. 리소스 추가


테이블 리스트의 각 아이템의 왼편에 보여질 아이콘(?) 이미지로 사용할 그림을 바탕화면이나 탐색기(?)에서 드래그 드럽으로 xcode로 가져온다.

3. 실행하기

cmt + R로 실행한다.


에디트 버튼 누르면 에디트 모드로 변한다




에디트 모드에서 아이템 왼편에 - 또는 + 모양이 있는데
-는 삭제 가능을, +는 추가가능을 의미한다.

+ 모양의 결정은 마지막 셀에 대해서 UITableViewCellEditingStyleInsert 를 리턴하여서 이렇게 나온것이다.

먼저 -를 눌러 삭제를 누르면 아이템이 사라진다.


만일 +를 누르면 It's new아이템이 생긴다.


만일 rearrange (위치 정렬)을 하고 싶으면 오른편의 - 짝대기 세개를 드래그 드럽하여 옮기면 된다.

이부분에 관한 코딩은 canMoveRowAtIndexPath 함수에서 마지막 아이템에 대해선 이동 불가로 해서 = 모양이 나타나지 않았다.
드래그 드럽으로 이동을 시키면 moveRowAtIndexPath 함수가 호출되어서 실제로 데이터도 옮겨야 한다.



문제는 New Item...이라는 마지막 아이템도 그냥 셀로 보고 이 아래로 옮길 수 있는데 .. 
이부분에 대해선 아직 완벽히 처리는 못했고 다만 bug fix로 New Item다음으로 셀을 이동되는 경우 문제를 뻑나는 문제를 해결하기 위해서

int toRow;

if( toIndexPath.row == [arr count] )

// fix bug

toRow = [arr count]-1;

else

toRow = toIndexPath.row;


[arr exchangeObjectAtIndex: fromIndexPath.row withObjectAtIndex: toRow];


위와 같이 처리하였다. 실제로 정확히 동작하려면 New Item..밑으로 아이템이 이동되어서 안될 것이다.

(사실 이동 가능하게 만드려면 New Item을 아이템으로 만들지 말고 Toolbar의 버튼으로 만드는게 낫지 않을까 다 하고 보니까 그런 생각이 들었다 ;;)

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


기본 네비게이션 기반 프로젝트로 생성하면 UITableViewController를 상속한 RootViewController가 존재한다.
이 테이블 리스트에 배열로 아이템을 넣은 후 네비게이션 바의 에디트 버튼을 누른 후 아이템을 삭제하도록 한다.

1. 프로젝트 생성

먼저 New/ New Project를 통해서 Navigation based 로 프로젝트를 생성한다.


2. 코딩

RootViewController

#import "RootViewController.h"

#import "TestNaviAppDelegate.h"


// NSMutableArray로 해야 배열 요소 삭제도 가능하다.

NSMutableArray *myarray; // data model


@implementation RootViewController


:


// 리스트에 표시될 아이템 갯수

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [myarray count];

}


// 테이블에서 특정 셀을 보여줘야 할 일이 생길떄 호출된다.

// NSIndexPath에는 section 컬럼과 row 몇번째 아이템인지 정보가 있다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *CellIdentifier = @"Cell";

    

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    }

    

    // Set up the cell

cell.text = [myarray objectAtIndex:indexPath.row];


    return cell;

}


// 뷰 시작할 때 테이블에 들어갈 데이터 배열을 생성
// (초기에 아무때나 어디서든 생성하면 된다. )

- (void)viewDidLoad {

    [super viewDidLoad];

    // Uncomment the following line to add the Edit button to the navigation bar.

self.navigationItem.leftBarButtonItem = self.editButtonItem;

myarray = [[NSMutableArray alloc] initWithObjects:@"First", @"Second", nil];

}




// Override to support editing the list

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        // Delete the row from the data source

// 실제 데이터에서 삭제를 해야 한다.

[myarray removeObjectAtIndex:indexPath.row];

// 아랫건 그냥 삭제되는 듯한 애니메이션만 하는 시늉 코드

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

    }   

    if (editingStyle == UITableViewCellEditingStyleInsert) {

        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

    }   

}



3. 실행

실행하면 아래 처럼 두개의 아이템이 보인다.



에디트 버튼을 누른다.


지우기를 하면 First가 사라진다.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST




Utility based로 프로젝트를 생성하면 appdelegate.h 소스엔 아래 처럼 되어 있습니다.

TestUtilDelegateApp.h

#import <UIKit/UIKit.h>


@class RootViewController;


@interface TestUtilAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

    RootViewController *rootViewController;

}


@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;


@end


그러나 소스 어디에도 어떻게 이 클래스가 생성되는지 적혀있지 않습니다.
하지만 실행하면 동작을 하지요.

main.m에는 다음과 같이 되어 있습니다.

main.m

#import <UIKit/UIKit.h>


int main(int argc, char *argv[]) {

    

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int retVal = UIApplicationMain(argc, argv, nil, nil);

    [pool release];

    return retVal;

}



UIApplicationMain은 아래와 같으며 4번쨰 delegateClass는 Nil이므로 UIApplication클래스가 되고
3번째 principalClassName은 nil이므로 info.plist에 있는 값을 사용하게 됩니다.

UIApplicaitonMain API

int UIApplicationMain ( int argc,  char *argv[], 
NSString *principalClassName, NSString *delegateClassName );


info.plist에는 MainWindow.xib 정보가 들어 있습니다.


MainWindow.xib는 File's Owner는 UIApplication이고 delegate가 된 것이 Test Util Application이다 그리고 이 Test Util App의 Inspector를 보면 TestUtilAppDelegate 클래스로 설정되어 있습니다.


마찬가지로 RootViewController에 대해서도 MainWindow.xib의 Root View Controller로 설정되어 있습니다.

UIApplicationMain 안에서 xib의 어떤 클래스와 연결되어 있는지 확인 한 후 여기에 설정한 클래스를 인스턴스 하게 되는 것입니다.
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


존칭이 없습니다. 양해 부탁드립니다. ^^


TabBar based 로 프로젝트를 생성한다.

먼저 이미지 파일을 두개 준비 한다. 첫 번쨰 이미지는 뷰에 첨부터 나오는 이미지로,
버튼 클릭하면 두번째 이미지로 변환시켜 본다.

1. 리소스에 이미지 추가하기

img.png와  img2.png를 데스크탑 바탕화면에서 드래그 드럽으로 워크스페이스 창 Resource노드에 추가한다.



2. FirstViewController에 UIImageView 추가 하기

FirstViewController.h

@interface FirstViewController : UIViewController {

IBOutlet UIImageView *view1;

IBOutlet UIButton *button1;

}


- (void)viewDidLoad;

- (IBAction) OnButtonDown : (id) sender;


@end


FirstViewController.m

// Implement viewDidLoad to do additional setup after loading the view.

- (void)viewDidLoad {

    [super viewDidLoad];

// [view1 setImage: [UIImage imageNamed: @"img2.png"]]; //만일 View로드 되자마자 이미지 바꾸고 싶으면 여기다가 하면 된다.

}


- (IBAction) OnButtonDown : (id) sender 

{

[view1 setImage: [UIImage imageNamed: @"img2.png"]];

}



3. TabBar의 첫 ViewController에 UIImageView를 추가하기

라이브러리 창에서 UIImageView를 추가한다.


UIImageView를 선택한 후 Tools/ Inspector 의 첫번째 탭의 Image를 img.png를 선택한다.

이렇게 하고 실행하면 바로 그림이 나온다.

4. 나머지 아울렛 연결

그러나 우리는 버튼이 눌리면 다른 그림으로 바꾸길 바라므로 아래와 같이 버튼 이벤트를 연결한다.

탭의 첫번째 First 라는 것을 오른클릭 잘해서 (잘 클릭하면 Inspector창에 FirstViewController라고 뜬다.)
아울렛들을 연결한다.
view1 -> UIImageView
button1 -> UIButton
OnButtonDown -> UIButton 후 TouchDown 연결


5. 실행하기

실행하면 img.png가 보인다.


이제 버튼을 누르면 이미지가 변경된다.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


존칭이 없는 포스트입니다. 양해 부탁드립니다 ^^

TabBar based로 프로젝트를 생성했을 경우 뷰에 있는 컨트롤을 동작시켜 본다.

TabBar based로 프로젝트를 생성한다.

1. FirstView에서 작업하기

먼저 FirstViewController 소스에 다음과 같이 추가한다.
이렇게 추가해 놔야 리소스 에디팅 (인터페이스 빌더)에서 아울렛을 연결할 수 있다.

FirstViewController.h

@interface FirstViewController : UIViewController {

IBOutlet UITextField *text1;

IBOutlet UIButton *button1;

}


- (IBAction) OnButtonDown: (id)sender;



@end


FirstViewControll.m

- (void)dealloc {

    [super dealloc];

}


- (IBAction) OnButtonDown: (id)sender

{

[text1 setText: @"Hello"];

}



@end


이제 저장을 한 후 MainWindow.xib를 더블클릭하여 인터페이스 빌더를 띄운다.

MainWindow.xib에 버튼과 텍스트필드를 추가한다.

문제는 MainWindow.xib안에 FirstViewController에 대한 ViewController가 없다. 
이 때 TabBar의 첫번째 First Item에서 오른클릭 해보자. 그러면 나온다;;
(이때 Tool/Inspector 창의  Class가 FirstViewController가 된 상태가 된다.)

아래처럼 button1, text1, OnButtonDown을 연결한다.


이렇게 하면 FirstView가 반응하게 된다.



2. SecondView 작업하기

SecondView는 이를 처리하는 ViewController가 프로젝트템플리트 소스에는 없다. 
따라서 먼저 SecondViewController 소스를 생성해야 한다. 

Project/ New Files 를 선택한 후
UIViewController로 선택한 후 SecondViewController이름으로 생성한다.

SecondViewController.h

@interface SecondViewController : UIViewController {

IBOutlet UITextField *stext1;

IBOutlet UIButton *sbutton1;

}


- (IBAction) OnSButtonDown: (id)sender;


@end


SecondViewController.m

- (void)dealloc {

    [super dealloc];

}


- (IBAction) OnSButtonDown: (id)sender

{

[stext1 setText: @"Hello Second"];

}




@end


저장한다.

이제 MainWindow.xib를 열어서 Second 탭바 아이템을 선택 한 후 아래처럼 Class를 SecondViewController로 변경한다.
Tools/Inspector를 연 후 네번째 탭의 Class을 아래 처럼 설정한다.



이제 SecondView.xib를 연다.
그리고 File's Owner의 inspector를 연 후 아래 처럼 class를 SecondViewController로 선택하고, 라이브러리 창으로 부터
텍스트 필드와 버튼을 올려 놓은다.



이제 File's Owner를 오른클릭하여 Second View의 sbutton1과 stext1, OnSButtonDown를 연결한다.



이제 실행 시켜 보면 두번째 뷰에서도 버튼이 동작함을 확인할 수 있다.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



본 튜토리얼은 존칭이 없습니다. 양해부탁합니다.


시작하기
 
본 튜토리얼은 iphone project 템플리트 중 View based를 선택하면 나오는 환경과 동일한 환경을 기본 windows based에서 만들어 보는 튜토리얼 이다.


먼저 Window based 로 프로젝트를 생성한다.

크게 다음과 같은 과정이다.
1. MyViewController class 생성
2. MyView.xib 생성
3. appDelegete 소스에 MyViewController 객체 생성

appDelegate.h
@class MyViewController;
MyViewController *viewController;
@property (nonatomic, retain) IBOutlet MyViewController *viewController;

appDelegate.m
#import "MyViewController.h"
@synthesize viewController;
[window addSubview:viewController.view];
[viewController release];

4. MyView.xib 에서 File's Owner를 view로 연결
- File's Owner의 Inspector 정보 탭에서 class를 MyViewController를 선택
- File's Owner를 view로 연결

5. MainWindow.xib에서 MyViewController 연결
- MainWindow.xib에 ViewController를 추가
- ViewController의 Inspector에서 NIB Name을 MyView로 선택
- ViewController의 Inspector에서 Class를 MyViewController를 선택
- My app delegate를 오른클릭하고 viewController객체를 ViewController로 연결


1. MyViewController class 생성

New File/ ViewController로 
MyViewController를 생성 (MyViewController.m, MyViewController.h가 생성됨)

2. MyView.xib 생성

New File/ Resource 중  
XIB View 선택 MyView생성 (MyView.xib 생성됨)


3. appDelegete 소스에 MyViewController 객체 생성

appDelegate.h에 다음을 추가함.
 

#import <UIKit/UIKit.h>

@class MyViewController;


@interface MyViewAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

    MyViewController *viewController;

}


@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet MyViewController *viewController;


@end



appDelegate.m에 다음을 추가함.
 

#import "MyViewController.h"

#import "MyViewAppDelegate.h"


@implementation MyViewAppDelegate


@synthesize window;

@synthesize viewController;



- (void)applicationDidFinishLaunching:(UIApplication *)application {    


    // Override point for customization after application launch

    [window addSubview:viewController.view];

    [window makeKeyAndVisible];

}



- (void)dealloc {  

    [viewController release];

    [window release];

    [super dealloc];

}



@end




4. MyView.xib 에서 File's Owner를 view로 연결

MyView.xib를 더블 클릭하여 연다음 먼저 xib파일의 소유자가 MyViewController임을 설정한다.

먼저 MyView.Xib의 File's Owner를 클릭한 후 Tool/Inspector를 연다음 인스펙터의 네번째 탭 ( i 표시 )의 Class Identity를 MyViewController로 설정한다.



이제 view가 대표 뷰임을 알리기 위해서 File's Owner를 오른클릭하면 ViewController의 view가 무엇인지 연결하는 view가 새로 생긴 것을 확인할 수 있는데, 이를 MyView.xib안의 View로 연결한다.


이것으로 MyView.xib에 관련된 연결은 끝이다.


5. MainWindow.xib에서 MyViewController 연결

먼저 MainWindow.xib에서 ViewController를 추가한다. 
라이브러리에서  뷰컨트롤러를 가져다가 MainWindow.xib창에 놓으면 추가된다.
MainWindow.xib에서 이 뷰컨트롤러를 MyViewController클래스로 연결하기 위해서 이다.



MainWindow.xib에서 생성된 View Controller를 선택하고 Tool/ Inspector를 클릭하여 인스펙터를 띄운다음 첫번째 탭의  NIB Name을 MyView로 선택한다. 그러면 Loaded From MyView.nib로 바뀐다.



인스펙터 창의 네번째 탭 (i)에서 클래스를 MyViewController를 설정한다.



이제 마지막으로 MainWindow.xib의 My View AppDeligate를 오른클릭하여 viewController를 My View Controller로 연결한다.


이것으로 모든 연결은 끝났다.


뷰에 버튼 클릭하기


MyViewController.h를 다음과 같이 추가한다.
먼저 UIButton, UITextField및 버튼 클릭 이벤트 함수 등은 미리 소스 (MyViewControll.h) 에서 만들어 둬야 한다.
이렇게 해야만 MyView.xib에서 아울렛 연결 시 text1, button1등이 나타나기 때문이다.

#import <UIKit/UIKit.h>



@interface MyViewController : UIViewController {

IBOutlet UIButton *button1;

IBOutlet UITextField *text1;

}


- (IBAction) OnButtonDown:(id) sender;


@end




MyViewController.m 은 다음과 같이추가한다.

- (void)dealloc {

    [super dealloc];

}


- (IBAction)OnButtonDown: (id)sender

{

[text1 setText:@"Textext"];

}



@end



MyView.xib에서 텍스트필드와 버튼을 생성한다.


MyView.xib 의 File's Owner를 오른클릭하여 button1과 text1을 view의 버튼과 텍스트 필드와 연결한다.

 


그리고 버튼이 눌리면 실행되는 OnButtonDown이벤트를 연결한다.





이 후에는 MyView.xib의 View에서 라벨이나 버튼을 놓고 cmd + R 하면 버튼 클릭시 텍스트가 변하는 것을 볼 수 있다.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



존칭이 생략되어 있습니다. 이점 양해 바랍니다 ^^


1. 프로젝트 코드 작성

먼저 프로젝트를 iphone windows based로 생성한다

그리고 아래와 같이 버튼과 텍스트필드를 위한 아울렛을 선언한다.
버튼 클릭이벤트를 받기 위해서 이벤트 핸들러 함수도 선언한다. (함수명은 마음대로)

testbuttonAppDelegate.h

//

//  testbuttonAppDelegate.h

//  testbutton

//

//  Created by Kyungmin Cho on 08. 09. 30.

//  Copyright __MyCompanyName__ 2008. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface testbuttonAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

IBOutlet UITextField *text1;

IBOutlet UIButton *button1;

}


@property (nonatomic, retain) IBOutlet UIWindow *window;


- (IBAction) OnButtonClick:(id)sender;


@end



이벤트 핸들링되면 텍스트 필드에 클릭이라고 출력되게 해보자.

testbuttonAppDelegate.m

//

//  testbuttonAppDelegate.m

//  testbutton

//

//  Created by Kyungmin Cho on 08. 09. 30.

//  Copyright __MyCompanyName__ 2008. All rights reserved.

//


#import "testbuttonAppDelegate.h"


@implementation testbuttonAppDelegate


@synthesize window;



- (void)applicationDidFinishLaunching:(UIApplication *)application {    


    // Override point for customization after application launch

    [window makeKeyAndVisible];

}



- (void)dealloc {

    [window release];

    [super dealloc];

}



- (IBAction) OnButtonClick: (id) sender

{

[text1 setText: @"click!"];

}


@end



2. 버튼, 텍스트필드 리소스 생성

이제 리소스 에디터에서 버튼과 텍스트필드를 추가한다.

Resources안의 MainWindow.xib를 더블클릭하면 InterfaceBuilder가 실행되며 
메인 윈도우 에다가 오른편에 있는 버튼과 텍스트필드를 드래그앤 드럽으로 가져오면 된다.


3. 아울렛 연결

이제 실제 코드와 리소스를 연결한다.
먼저 MainWindow.xib 창의 testbuttonApp...를 선택하고 오른클릭 하면 코드로 적어놨던 text1과 button1이 있음을 알 수 있다.
버튼과 텍스트를 아래 그림처럼 동그라미 안에서 드래그 드럽으로 원하는 Window 창의 각 버튼 텍스트에 연결한다.



마지막으로 버튼 클릭 이벤트 함수 연결은 
Received Actions의 내가 코딩했던 OnButtonClick함수의 동그라미에서 드래그앤 드럽으로 Window의 버튼으로 연결하면
아래와 같이 버튼의 어떤 액션에 연결할겨냐고 나오는데 TouchDown으로 연결하면 된다.



4. 실행

cmd + R을 눌르거나 Debug and Run을 실행하면 iPhone simulator가 실행되며 버튼 누르면 click이라는 글짜가 텍스트 필드에 나타난다.





YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon repair iphone 2011.06.14 20:17 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다. 제가 이글 퍼가도 되죠?



티스토리 툴바