오프라인 스터디에서 매주 배운 것을 정리 및 공유하고자 이렇게 스터디 내용을 씁니다.

첫번째 시간은 피해갈 수 없는 Hello, World 입니다.. 전 Hello, iPhone으로 명명 하겠습니다.
스터디 목표는 다음과 같습니다.
- 뷰베이스의 프로젝트를 생성하여 헬로우 프로그램을 작성
- 윈도우베이스의 프로젝트를 생성하고 헬로우 프로그램 작성(xib, controller, delegate를 각각 입력)
- 두 프로젝트를 비교 분석하여 iPhone Cocoa모델의 전반적 흐름을 이해

1.Xcode를 실행 하면 Welcom to Xcode라는 화면의 프로젝트 선택 화면이 나타납니다.
자.. 이제 프로젝트를 생성해 봅시다. Create a new Xcode project를 선택합니다.



다음 화면은 프로젝트가 어떤 베이스로 Template을 생성하는가? 입니다.
좌측의 Application 선택하고  View-Base Appicaton을 선택합니다. 그리고 프로젝트명을 입력합니다.
전 HelloiPhone이라는 프로젝트명으로 생성을 완료~





자 생성된 주요 파일은 다음과 같습니다.
다음 파일은 기억해 두세요..
HelloiPhoneAppDelegate / HelloiPhoneViewController /HelloiPoneViewController.xib / MainWindow.xib



2. HelloiPhoneViewController.xib를 더블클릭하여 IB(Interface Builder)를 실행합니다
다음과 같이 View 윈도우에 라벨을 추가 후 텍스트를 입력합니다.

          

3. 여기서 주의 하실 것이 IB와 Xcode는 각각의 프로그램 입니다.
하나의 프로그램이 아니기 때문에 IB에서 저장을 해야 XCode의 xib파일에 반영이 됩니다.
cmd+s(저장)를 눌러주세요. 그리고 Xcode에서 Build & Run을 실행합니다.
위과 같이 에뮬레이터에서 Hello, iPhone을 보실 수 있습니다.

============================================================
윈도우 베이스의 Hello, iPhone 작성~
============================================================
1. 뉴 프로젝트 생성 시 Window-base Application을 선택 합니다. 저는 프로젝트명을 HelloiPhone2로 하였습니다.
보시는 것과 같이 프로젝트에 생성된 파일 중에 HelloiPhoneController,h/m 및 HelloiPhoneController.xib 파일이 생성되지 않습니다.
이번 프로젝트에서는 두파일 직접 추가,  IB 설정을 하겠습니다.




2. 우선 ViewController 클래스를 생성 해보겠습니다. cmd+n을 누르시거나 파일-뉴파일을 선택 합니다. 좌측 상단의 Cocoa Touch Class클릭 후 UIViewController를 선택하여 생성합니다.
여기서 주의 하실 점이 중간에 있는 옵션 체크 박스입니다. 만들 클래스가 UITableViewController SubClass가 아니기 때문에 언체크....또 With XIB for user interface.. 옵션도 언체크.. 이옵션은 클래스 생성시 해당 뷰클래스의 xib도 같이 생성하는 옵션인데 이번 스터디에서는 cocoa의 구조를 알기 위함이라 체크를 하지 않습니다... 조금뒤에 직접 xib 파일도 추가 하니..신경 쓰지 마시길..
저는 HelloiPhoneViewController라고 파일명을 주었습니다.



3. 생성된 클래스를 MainWindow와 연결하기 위해 HelloiPhone2AppDelegate.h 파일을 열어 다음을 추가 코딩 합니다.

/*HelloiPhone2AppDelegate.h*/
#import <UIKit/UIKit.h>
//생성된 클래스 선언 #import "HelloiPhoneViewController.h" 를 선언도 동일함
@class HelloiPhoneViewController;

@interface HelloiPhone2AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    //추가된 클래스의 객체를 선언
    HelloiPhoneViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
//객체생성(메모리 할당)
@property (nonatomic, retain) IBOutlet HelloiPhoneViewController *viewController;
@end

=====================
/*HelloiPhone2AppDelegate.m*/

#import "HelloiPhone2AppDelegate.h"
//헤더 부분에 import를 하지 않고 class 선언을 했을 경우 바디 파일에서 꼭 import 선언
#import "HelloiPhoneViewController.h"

@implementation HelloiPhone2AppDelegate

@synthesize window;
//get, set 사용을 위한 synthesize 선언
@synthesize viewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // Override point for customization after application launch
    // 메인윈도우에 view추가
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}
- (void)dealloc {
    [window release];
    //메모리 해제
    [viewController release];
    [super dealloc];
}
@end

4. HelloiPhoneViewController.xib 파일을 만들어 보겠습니다. cmd+n을 누릅니다.
새 파일 생성에서 좌측 User Interface 클릭 후 view xib를 선택 합니다.
xib 파일은 모두 생성이 완료 되었습니다.. 이제 xib와 생성한 controller 클래스간의 연결을 해봅시다.
먼저 MainWindow.xib를 연결해 보겠습니다. 처음 coontroller 클래스를 생성시 wiith xib for user interface 체크를 선택 하고 controller 클래스를 생성 하였다면 MainWindow.xib의 연결 설정을 할 필요는 없지만.. 이번에는 선택을 하지 않고 생성 하였기 때문에 우선 서로 연결을 해봅니다.
MainWindow.xib를 더블클릭으로 IB를 실행 시킵니다. 아래와 같이 Window.xib 창에는 어떠한 View Controller가 포함 되어 있지 않네요..



우선 Window 창에 View Controller를 추가 해보겠습니다. Library 에서 View Controller를 선택 합니다.
(노랑 바탕의 View입니다 흰바탕의  View와 혼동하지 마시길 바랍니다.) 드래그를 하여 File's Onewr/First Responder/... 등의 내용이 보이는 MainWindow.xib 윈도우 창에 View Controller를 놓습니다. 그럼 아래와 같이 하나의 View Controller 창이 새로 생성이 됩니다... 자 이제 연결을 해봅시다.



먼저 View Controller를 선택하고 Inspector(아래의 창입니다) 에서 cmd+1을 누릅니다. 그러면 속성 창으로 탭이 변경됩니다. (Inspector 창의 각 탭은  cmd+1..2..3..4로 탭창이 변경 가능 합니다.)
아래와 같이 nib name을 HelloiPhonViewController로 변경 합니다.



 그리고 cmd+4를 눌러 Identy Inspector 탭을 엽니다 4번째 탭... 여기서 Class를 HelloiPhoneViewController로 변경 합니다.



다음은 Hello iPhone2 AppDelegate를 선택하여 아래의 그림과 같이 연결을 합니다. Hello iPhone2 AppDelegate 의 연결이 완료 되면  HelloiPhoneController 에도 연결된 내용이 등록됩니다.





5. 자.. 마지막으로 HelloiPhoneViewController.xib 파일을 편집해보겠습니다..
먼저..HelloiPhoneViewController.xib를 더블클릭 해서 IB에 로드합니다.
View에 라벨을 올리고 Hello, iPhone 이라고 디자인을 합니다.
그리고 File's Owner를 클릭 Identy Inspector창을 띄웁니다(cmd+4) 그리고 class 를 HelloiPhoneViewController로 변경합니다.



그리고 File's Owner의 Connection을 연결합니다.



그러면 자동으로 View에도 Connection이 등록 됩니다.



자 이제 Build & Run 을 실행... 동일한 결과를 보실 수 있어요 ^^



수고 하셨습니다..  곰곰히 생각해보세요 흐름을...
중요한 것은 Connnection을 하기전 해당 클래스를 사용자가 추가한 클래스로 변경 한다는 것입니다. 
MainWindow의 경우는 nib name도 같이 변경을 해야 합니다..

잘되지 않을 경우 xcodenine@G메일.컴 으로 연락 주세요
ㅋㅋㅋ 자세히 설명 드릴께요...

정말 수고하셨어요 ^^ 다음 스터디 내용은
여러개의 뷰에 대한 스위칭 입니다. 시간이되면 툴바 및 텝바에 대해서도 진행 합니다.
다음 스터디에 뵙겠습니다.




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

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:47
UItableView customizing with Addressbook (네번째 스터디)
안녕하세요.. 금일은 전 시간에 진행했던 테이블뷰에 대해서 쪼금 더 심도 있게 진행을 하겠습니다.
제목을 봅시다... 네 테이블뷰의 커스텀마이징 입니다...

@ 학습목표
- UITableViewCell 을 이용하여 테이블뷰 꾸미기
- ABAddressbook 프레임 워크 이용하기

개요를 말씀드리자면 IB를 이용한 커스텀셀을 생성하는 방법과 코딩으로 하는 방법 2가지가 있습니다 우선 모두다 해보겠습니다.
추가적인 보너스로 테이블의 내용을 iPhone 내부의 주소록을 데이터를 이용하여 만들어 보겠습니다..
이름하여 인맥북!!!! ㅋㅋ 귀찮으시더라도 시뮬레이터의 주소록에 이미지를 추가해 놓습니다. 그래야 이미지가 나와요..

먼저 뷰콘트롤러 기반의 포르젝트를 생성합니다.. 저는 ownLinks 라고 명명.. 하겠습니다. 
IB를 로드 해서 UITableView 를 추가합니다. 그리고 UITableView를 선택해서 connection을 설정합니다. delegate, dataSouce는 File's Owns와 연결을 합시다.. 그리고 세이브 해주시고 소스 코드로 돌아갑니다.



먼저 IB를 사용 하지 않고 Cell 을 디자인 해보겠습니다.
addressbook을 사용하기 위해서는 AddressBook/AddressBookUi 라는 2가지 프레임워크를 이용합니다. 
먼저 AddressBook 프레임 워크 입니다.. 네 이건 주소록 데이터를 읽어오고 편집 추가 저장 등을 할 수 있는 메서드들을 제공합니다.
두번째 프레임 워크인 AddressBookUI 는 말그대로 UI와 데이터를 연결하는 Delegate 메서드를 정의 합니다(사용은 아직 안해봐서 정확한 표현인지는 모르겠습니다만...)

저는 주소록의 데이터를 제가 만든 커스텀마이징된 테이블뷰에 넣기 위해서  AddressBook 프레임 워크만을 사용하였습니다.

프레임워크 파일을 프로젝트에 추가 합니다.

                                       

먼저 viewController.h 파일에 사용할 프레임 워크를 인포트 하고 프로토콜들을 추가 합니다.

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h> // 프레임워크 추가
//UITableViewCell 하위 뷰의 구분자 선
#define kNameValueTag 1
#define kNumberValueTag 2
#define kImageTag 3

@interface ownLinksViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, > {
}
@end

다음는 바디 코드 입니다. 나머지 부분은 생략을 하고 제일 중요한 프로토콜 구현 부부입니다.

#pragma mark -
#pragma mark Table View Data Source Methods

-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
        // 테이블 수는 연락처에 입력된 연락처 수
ABAddressBookRef addressBook = ABAddressBookCreate();
NSInteger size = (NSInteger)ABAddressBookGetPersonCount(addressBook);
CFRelease(addressBook);
return size;
}

//tag값에 선언된 상수를 입력하여 해당 서버 뷰들을 구분한다.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell 구분자 언언
static NSString *CellTableIdentifier = @"CellTableIdentifier ";
//cell 존재 검사
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
if (cell == nil) {
              //cell 선언
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellTableIdentifier] autorelease];
        
               //cell에 들어갈 이미지 설정 
     CGRect imageViewRect = CGRectMake(5, 5, 30, 30);
UIImageView *personView = [[UIImageView alloc] initWithFrame:imageViewRect];
personView.tag = kImageTag;
[cell.contentView addSubview:personView];
[personView release];
        CGRect nameLabelRect = CGRectMake(35, 5, 65, 15);
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
        nameLabel.textAlignment = UITextAlignmentRight;
        nameLabel.text = @"Name:";
        nameLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: nameLabel];
        [nameLabel release];
        
        CGRect numberLabelRect = CGRectMake(35,25, 65, 15);
        UILabel *numberLabel = [[UILabel alloc] initWithFrame:numberLabelRect];
        numberLabel.textAlignment = UITextAlignmentRight;
  numberLabel.text = @"Number:";
        numberLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: numberLabel];
        [numberLabel release];
        
        CGRect nameValueRect = CGRectMake(110, 5, 200, 15);
        UILabel *nameValue = [[UILabel alloc] initWithFrame:nameValueRect];
        nameValue.tag = kNameValueTag;
        [cell.contentView addSubview:nameValue];
        [nameValue release];
        
        CGRect numberValueRect = CGRectMake(110, 25, 200, 15);
        UILabel *numberValue = [[UILabel alloc] initWithFrame:numberValueRect];
        numberValue.tag = kNumberValueTag;
        [cell.contentView addSubview:numberValue];
        [numberValue release];
        
}
//선택된 인덱스
 NSUInteger row = [indexPath row];  

//ABAdrressBookCreate()를 이용하여 현재 주소록 객체를 생성
ABAddressBookRef addressBook = ABAddressBookCreate();
//저장된 개인목록을 복사(Group 데이터는 ABAddressBookCopyArrayOfAllGroups를 이용
//개인 목록과 그룹 목록으로 구분되어 저장되어 있
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
//선택된 row 의 개인 정보 가져옴 
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, row);

//태그를 이용하여 라벨을 찾는다.
  UILabel *name = (UILabel *)[cell.contentView viewWithTag:kNameValueTag];
//개인정보 중 firstname 만 복사함 kABPersonFirstNameProperty 같은 각각의 인자가 정의 되어 있다.
name.text = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);

//전화번호부를 복사 여러개의 전호 번호가 존재하기 때문에 해당 데이터는 멀티 값을 가지는 배열로 저장되어 있다.
ABMutableMultiValueRef multi =  ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(multi);
//전화 번호가 없는 경우 nil 값을 가진다.
if (phoneNumbers != nil) {
UILabel *number = (UILabel *)[cell.contentView viewWithTag:kNumberValueTag];
                //전화 번호는 배열로 저장되어 있기 때문에 원하는 정보가 위치한 index를 인자로 넘겨준다.
number.text = [phoneNumbers objectAtIndex:0];
}
//이미지를 가지는 검사 
if (ABPersonHasImageData(ref)) {
    // 이미지를 복사 하여 이미지 뷰에 입력
     // CFDataRef 데이터 형식으로 리턴된다. 형변환을 하여사
UIImage *personImage = [[UIImage alloc] initWithData:(NSData*)ABPersonCopyImageData(ref)];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:kImageTag];
imageView.image = personImage;
[personImage release];
}
//프레임워크를 이용하여 생성된 객체(포인터아님)자원은 CFRelease를 이용하여 해제한다. 
CFRelease(multi);
CFRelease(ref);
//문제 발생
//ABAddressBookCreate, ABAddressBookCopyArrayOfAllPeople 를 이용하여 생성된 객체
//둘다 해제하게되면 메모리 크래쉬가 일어 난다. 둘중에 하나만 해제를 하여 사용
//원인을 추축하면 생성되는 시 같은 데이터를 참조하는게 아닐까 하는 추축이다... 구글링을 좀더 해서 원인을 
//파악해 야될것 같네요.
CFRelease(addressBook);
//주석처리..
// CFRelease(allPeople);

return cell;
}

이것을 실행하면 아래와 같이 나옵니다..




IB를 이용하는 방법은 이어 작성 하겠습니다.





 



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

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:46
나도 한다.. 테이블뷰~(세번째 스터디)
지난주에 진행한 내용은 아래와 같습니다.
-UITableView 사용
-UITableViewCell 사용

프로젝트 생성은 윈도우 베이스에서 UITableViewController를 추가를 하여도 되고 뷰기반으로 생성후 해당 UITableView를 추가 하여도 됩니다. 전 두번째 방법으로 진행을 하겠습니다.

먼저 프로젝트를 생성합니다. 뷰기반으로 프로젝트를 생성합니다. SimpleTale 이라고 하겠습니다.
SimpleTableViewController.xib 를 더블클릭합니다. Object에서 TableView를 선택합니다. 그리고 입력한 테이블 뷰를 선택한 상태로 cmd+2를 실행하여 Table View Connection 탭을 띄워서 delegate와 datasource를 File's Owner에 연결합니다.



저장 후 SimpleTableViewController.m/h에 코드를 추가 합니다.
먼저 헤더..

#import <UIKit/UIKit.h>

@interface SimpleTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    NSArray *listData;
}
@property (nonatomic, retain) NSArray *listData;
@end

테이블뷰를 사용하기 위한 프로토콜인 UITableViewDelegate, UITableViewDataSource 를 선언합니다.
다음 데이터를 저장할 배열인 listData를 선언합니다.

다음은 바디..
테이블에 들어갈 배열값을 초기화 합니다.

#import "Simple_TableViewController.h"

@implementation Simple_TableViewController
@synthesize listData;
- (void)viewDidLoad {
    NSArray *array = [[NSArray alloc] initWithObjects:@"Sleepy", @"Sneezy",
                      @"Bashful", @"Happy", @"Doc", @"Grumpy", @"Dopey", @"Thorin",
                      @"Dorin", @"Nori", @"Ori", @"Balin", @"Dwalin", @"Fili", @"Kili",
                      @"Oin", @"Gloin", @"Bifur", @"Bofur", @"Bombur", nil];
    self.listData = array;
    [array release];
    [super viewDidLoad];
}

메모리 해제...
- (void)viewDidUnload {
    self.listData = nil;
    [super viewDidUnload];
}
- (void)dealloc {
    [listData release];
    [super dealloc];
}

예 제 소스의 핵심인 프로토콜 구현 부분입니다. 필수 프로톨을 구현하지 않을 경우 컴파일 시 경고로 표시됩니다.
테이블 뷰는 delegate와 datasoure 부분의 프로토콜을 기본적으로 사용합니다.
deletegate는 테이블 뷰의 동작, 상태에 대한 정의이고 datasource는 테이블 뷰의 레코드 데이터에 대한 내용을 포함하고 있습니다.

=====================
          데이터 소스 메소드
=====================

pragama는 함수와 함수 사이의 색인 역활을 합니다.
#pragma mark -
#pragma mark Table View Data Source Methods



테이블이 가지는 row즉 레코드의 수를 설정하는 프로토콜입니다.. 필수!
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    return [self.listData count];
}

아주 중요한 프로토콜입니다.
테이블뷰가 그려질 행이 있을 경우 호출하는 메소드 입니다.  많은 레코드들 중 화면에 나타는 레코드들이 대상입니다.

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //레코드를 구분하는 식별자 선언
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";

   // 레코드의 내용은 iPhone OS에서 관리하고 레코드를 저장하는 자료 구조는 dequerue로 구성 되어 있습니다.
   // 식별자로 검색을 하여 해당 데이터가 없을 경우 새로 생성을 합니다.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             SimpleTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier: SimpleTableIdentifier] autorelease];
    }
    //간단히 이미지 추가
    UIImage *image = [UIImage imageNamed:@"star.png"];
    UIImage *image2 = [UIImage imageNamed:@"star2.png"];
    cell.imageView.image = image;
    //레코드가 선택된 경우 2번째 이미지를 로드
    cell.imageView.highlightedImage = image2;

    NSUInteger row = [indexPath row];
    cell.textLabel.text = [listData objectAtIndex:row];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:50];
  
   //cell의 뒷부분에 넣을 문자
    if (row < 7)
        cell.detailTextLabel.text = @"Mr. Disney";
    else
        cell.detailTextLabel.text = @"Mr. Tolkein";

    return cell;
}

=====================
         딜리게이트  메소드
=====================

레코드의 들여쓰기를 설정
- (NSInteger)tableView:(UITableView *)tableView
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    return row;
}

선택된 레코드의 indexpath를 통해 값이 유요한지 검사
-(NSIndexPath *)tableView:(UITableView *)tableView
 willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    if (row == 0)
        return nil;
   
    return indexPath;
}

핵 심 프로토콜 입니다. 해당 레코드(셀)을 선택 했을 경우 호출 됩니다.
willSelectRowAtIndexPath 가 수행되고 다음으로 호출되는 메서드 입니다.
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    NSString *rowValue = [listData objectAtIndex:row];
   
    NSString *message = [[NSString alloc] initWithFormat:
                         @"You selected %@", rowValue];
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"Row Selected!"
                          message:message
                          delegate:nil
                          cancelButtonTitle:@"Yes I Did"
                          otherButtonTitles:nil];
    [alert show];
   
    [message release];
    [alert release];
    //선택된 셀을 다시 해지한다.
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

// 셀 높이를 설정
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 70;
}

빌드 & 런을 합니다. 실행결과는 다음과 같습니다.



두번째 내용인 UITableViewCell 다음 게시물에 이어서 작성 하겠습니다.
쓰다보니 코드만 잔뜩 있네요.. 책의 내용과 100프로 동일하네요..

주소록 만드는 것을 작성하려고 하였으나.... 스터디와 진행한 내용에 벗어나서 그건 따로 정리하면 올리겠습니다.
즐거운 하루되세요..



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

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:46
멀티뷰 스위칭..(두번째 스터디)
안녕하세요.. 금주에는 멀티뷰 스위칭 내용에 대하여 스터디를 진행합니다.

학습 목표
- 한 개의 메인콘트롤러 뷰와 2개의 서브뷰를 이용하여  ViewController Switching
- 각각의 뷰에 이미지 로드(IB와 code 작성을 이용한)
- 툴바 이용하여 Switch Action 구현하기...
- 화면 이동 시 에니메션 효과 넣기

* 이번 스터디 부터는 생성되는 프로젝트 및 클래스들의  xib팡일은 자동으로 생성합니다.

View마다 각각 xib를 생성, 디자인도 가능하고 또는 MainWindow.xib에 ViewController를 추가하여 디자인도 가능합니다. 하지만 유지보수 및 편의상 각각의 view.xib를 만들어서 진행 하도록 하겠습니다.

우선 프로젝트를 ViewController 기반으로 생성을 합니다. 저는 MultiViewSwitch라고 명명했습니다. 자동으로 MultiViewController가 MainWindow와 연결이됩니다 .. 따로 IB설정을 할 필요는 없습니다. 

1. 툴바 추가하기
MultiViewController의 xib파일을 더블클릭하여 IB를 호출 합니다. libray창에서 UIToolbar 선택하여 뷰하단에 추가합니다. 

생성된 툴바는 좌측으로 버튼이 하나가 자동으로 생성됩니다. 이렇게 자동으로 생성된 버튼은 이동을 할 수 없지요. 자 그럼 이동을 위해서 아래와 같이 UIBarButtonItem을 이용하여 가능합니다. 
두가지 타입이 있죠.. Fixed Space Bar button Item/Flexible Space Bar Button  입니다.. 두가지의 차이점은 보시는 것과 틀립니다.. Fixed는 바의 버튼의 크기가 늘어 나지 않고  Flexible 자동으로 좌우측중 한 곳으로 버튼이 고정되서 늘어나게 됩니다..


이번엔 Bar에 버튼을 추가 해봅시다. xib윈도를 계층적으로 정리해서 펼쳐보면 다음과 같이 나타 납니다... 

이제 library에서 Bar Button Item을 추가합니다. 그럼 다음과 같이 하위에 하나의 클래스가  더 추가가됩니다. 

툴바의 디자인 완료. 버튼의 이름을 정해주세요.

이제 메인뷰는 MultiViewController가 되고 서브뷰인 FirstViewController와 SecondViewController를 생성합니다. 생성시 아래와 같이 With XIB for user interface를 체크 하고 진행 합니다..그럼 클래스 파일과 xib파일이 자동으로 생성이 됩니다.

다음으로 이미지를 해당 뷰에 삽입해 보겠습니다. 여기서  IB에서 설정하여 xib가 로드될 때 이미지가 바로 설정되는 방법과 프로그램 코드에 직접 코딩해서 이미지를 로드하는 방법 가능합니다. 
모두 구현해 봅시다. 
우선 프로젝트에 2개의 이미지 파일을 추가 합니다.. (option+cmd+A) FirstImage/SecondImage 를 추가 합니다.

첫번째.. IB 이미지 설정..
우선 View를 선택하시고 cmd+!를 누르시고 Inspector-View Attributes의 Bottom Bar를 설정합니다. 그럼 View의 크기가 툴바를 제외한 크기로 자동으로 마춰집니다.

이제 Image View를 선택하여 추가 합니다.
Image View를 선택하고 View Attributes 에서 Image-FirstImage와 Mode-Scale to fill 를 선택 합니다. 이미지는 프로젝트에 추가가되어 있어야 나타납니다.


두번째 FirstView를 디폴트뷰로 설정을 해봅시다.
메인콘트롤러뷰에 코드를 작성해 보겠습니다.(MultiViewSwitchController.h/m)

먼저 헤더 파일 입니다.

#import <UIKit/UIKit.h>
//먼저 헤더 파일 import
#import "FirstViewController.h"
#import "SecondViewController.h"

@interface MultiViewSwitchViewController : UIViewController {
//서브뷰들을 선언 합니다.
FirstViewController *firstView;
SecondViewController *secondView;
}

@property (nonatomic, retain) FirstViewController *firstView;
@property (nonatomic, retain) SecondViewController *secondView;

@end

스위치 Action 메시지는 조금 뒤에 작성하겠습니다.
다음은 바디입니다.

#import "MultiViewSwitchViewController.h"

@implementation MultiViewSwitchViewController
@synthesize firstView;
@synthesize secondView;

- (void)viewDidLoad {
//디폴트 뷰 설정
//!주의 initWithNibName 파라미터는 해당 view의 xib 파일명과 동일함
FirstViewController *firstController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    self.firstView = firstController;
//현재 뷰의 서브뷰입력 insertSubView와 addSubView의 차이점은 
//insertSubView 해당 인덱스의 뷰를 교체함
//addSubView는 서브뷰의 마지막 인덱스에 뷰를 추가함
[self.view insertSubview:firstController.view atIndex:0];
[firstController release];
[super viewDidLoad];
}

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

- (void)dealloc {
[firstView dealloc];
[secondView dealloc];
    [super dealloc];
}

자.. 이제 빌드 앤 런을 하면 다음과 같은 실행 화면을 보실 수 있습니다!


두번째 코드로 이미지 불러오기를 해보겠습니다.
SecondViewController.m에 다음의 코드를 추가 합니다.

- (void)viewDidLoad {
// 뷰가 로드 될 때 이미지 파일 로드
UIImage *secondImage =[UIImage imageNamed:@"SecondImage.png"]; 
UIImageView *imageView = [[UIImageView alloc] initWithImage:secondImage];
//이미지의 크기를 설정한다. 이 크기는 툴바를 제외한 이미지 뷰의 크기
imageView.frame = CGRectMake(0, 0, 320, 416);
//소스 변경 깜박임 수정
//프레임 크기 설정 후 이미지 설정
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)];
[imageView setImage:secondImage];
//서브뷰에 이미지를 추가 
[self.view addSubview:imageView];
         //서브뷰 이미지를 뒤로 보냄(사용하지 않을 경우 디자인된 컨트롤을 덮음)
[self.view sendSubviewToBack:imageView];
[imageView release];
[super viewDidLoad];
}

위 코드의 문제점은 에니메션이 진행되는 동안 뷰의 사이즈가 변경되기때문에 화면이 깜박이는 문제점이 있습니다. 제 생각에는 프레임 조정 후 이미지를 넣으면 될 것 같은데...음.. 집에가서 해보겠습니다. 다른 해결 방법을 아시는 분은 답변 부탁 드립니다.

이제 나머지 소스인 SecondView로드 Action메소드를 넣어봅시다.
MultiViewSwitchViewController.h는 다음과 같습니다.

-(IBAction)switchViews:(id)sender;

바디에 Action 메시지를 추가 합니다.
- (IBAction)switchViews:(id)sender
{
    [UIView beginAnimations:@"View Flip" context:nil];
    [UIView setAnimationDuration:1.25];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    
    if (self.secondView.view.superview == nil)
    {
        if (self.secondView == nil)
        {
            SecondViewController *secondViewController = 
            [[SecondViewController alloc] initWithNibName:@"SecondViewController" 
                                                   bundle:nil];
            self.secondView = secondViewController;
            [secondViewController release];
        }
        [UIView setAnimationTransition:
         UIViewAnimationTransitionFlipFromRight
                               forView:self.view cache:YES];
        
        [firstView viewWillAppear:YES];
        [secondView viewWillDisappear:YES];
        [firstView.view removeFromSuperview];
         //뷰 이미지 교체 
        [self.view insertSubview:secondView.view atIndex:0];
        [secondView viewDidDisappear:YES];
        [firstView viewDidAppear:YES];
    }
    else
    {
        if (self.firstView == nil)
        {
            FirstViewController *firstViewController = 
            [[FirstViewController alloc] initWithNibName:@"FirstViewController" 
                                                 bundle:nil];
            self.firstView = firstViewController;
            [firstViewController release];
        }
        [UIView setAnimationTransition:
         UIViewAnimationTransitionFlipFromLeft
                               forView:self.view cache:YES];
        
        [secondView viewWillAppear:YES];
        [firstView viewWillDisappear:YES];
        [secondView.view removeFromSuperview];
        [self.view insertSubview:firstView.view atIndex:0];
        [firstView viewDidDisappear:YES];
        [secondView viewDidAppear:YES];
    }
    [UIView commitAnimations];
}


 SecondViewController   이게 아니군요.. MultiSwitchViewController 의 IB를 실행 합니다. 
다음과 같이 액션 메시지를 연결 시켜 줍니다.

일단 여기까지 하시면 스위칭 되는 뷰의 모습을 보실 수 있습니다..

아직 마지막 부분이 조금 미작성 되었네요.. Alert 창을 띄우는 누구세요? 버튼에 대한 동작을 추가 작성 해야됩니다.
오늘 저녁에 추가 작성하겠습니다.

추가 작성 코드... 계획은 누구세요 버튼을 hidden 시키고 다음 페이지에 나타나게 하는 것이 였는데
UIBarButtonItem 가 숨김 속성 또는 숨김 메시지를 가지고 있지 않네요.. 그래서 그냥 Alert 창만 넣었습니다.
추가 코드는 다음과 같습니다 MultiSwitchViewControll에 작성하시면 됩니다.
먼저 헤드 파일

-(IBAction)pressed:(id)sender;

다음 바디..

-(IBAction)pressed:(id)sender
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"She said" message:@"I'm Jessica Gomes." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
}

다음은 위 이미지와 같이 pressed 함수를 버튼과 연결 하면 됩니다.. 이미지는 생략 하겠습니다..

이제 컴파일 해보시고 결과를 확인해 보세요..
두번째 이미지가 궁금하신분들은 소스 받이서 돌려보시길..

두번째 스터디도 수고 하셨구요.. 열공합시다.. 파이팅!

중간에 설명이 부족한 부분이나 틀린부분은 지적해 주세요.. 
작성한 소스는 오늘 집에 가는데로 업로드 하겠습니다. 회사라서..

궁금하신 점이 있으면 리플 리플 달아주세요~


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

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:46
Hello, iPhone 프로그래밍 시작하기...(첫번째 스터디)
오프라인 스터디에서 매주 배운 것을 정리 및 공유하고자 이렇게 스터디 내용을 씁니다.

첫번째 시간은 피해갈 수 없는 Hello, World 입니다.. 전 Hello, iPhone으로 명명 하겠습니다.
스터디 목표는 다음과 같습니다.
- 뷰베이스의 프로젝트를 생성하여 헬로우 프로그램을 작성
- 윈도우베이스의 프로젝트를 생성하고 헬로우 프로그램 작성(xib, controller, delegate를 각각 입력)
- 두 프로젝트를 비교 분석하여 iPhone Cocoa모델의 전반적 흐름을 이해

1.Xcode를 실행 하면 Welcom to Xcode라는 화면의 프로젝트 선택 화면이 나타납니다.
자.. 이제 프로젝트를 생성해 봅시다. Create a new Xcode project를 선택합니다.



다음 화면은 프로젝트가 어떤 베이스로 Template을 생성하는가? 입니다.
좌측의 Application 선택하고  View-Base Appicaton을 선택합니다. 그리고 프로젝트명을 입력합니다.
전 HelloiPhone이라는 프로젝트명으로 생성을 완료~





자 생성된 주요 파일은 다음과 같습니다.
다음 파일은 기억해 두세요..
HelloiPhoneAppDelegate / HelloiPhoneViewController /HelloiPoneViewController.xib / MainWindow.xib



2. HelloiPhoneViewController.xib를 더블클릭하여 IB(Interface Builder)를 실행합니다
다음과 같이 View 윈도우에 라벨을 추가 후 텍스트를 입력합니다.

          

3. 여기서 주의 하실 것이 IB와 Xcode는 각각의 프로그램 입니다.
하나의 프로그램이 아니기 때문에 IB에서 저장을 해야 XCode의 xib파일에 반영이 됩니다.
cmd+s(저장)를 눌러주세요. 그리고 Xcode에서 Build & Run을 실행합니다.
위과 같이 에뮬레이터에서 Hello, iPhone을 보실 수 있습니다.

============================================================
윈도우 베이스의 Hello, iPhone 작성~
============================================================
1. 뉴 프로젝트 생성 시 Window-base Application을 선택 합니다. 저는 프로젝트명을 HelloiPhone2로 하였습니다.
보시는 것과 같이 프로젝트에 생성된 파일 중에 HelloiPhoneController,h/m 및 HelloiPhoneController.xib 파일이 생성되지 않습니다.
이번 프로젝트에서는 두파일 직접 추가,  IB 설정을 하겠습니다.




2. 우선 ViewController 클래스를 생성 해보겠습니다. cmd+n을 누르시거나 파일-뉴파일을 선택 합니다. 좌측 상단의 Cocoa Touch Class클릭 후 UIViewController를 선택하여 생성합니다.
여기서 주의 하실 점이 중간에 있는 옵션 체크 박스입니다. 만들 클래스가 UITableViewController SubClass가 아니기 때문에 언체크....또 With XIB for user interface.. 옵션도 언체크.. 이옵션은 클래스 생성시 해당 뷰클래스의 xib도 같이 생성하는 옵션인데 이번 스터디에서는 cocoa의 구조를 알기 위함이라 체크를 하지 않습니다... 조금뒤에 직접 xib 파일도 추가 하니..신경 쓰지 마시길..
저는 HelloiPhoneViewController라고 파일명을 주었습니다.



3. 생성된 클래스를 MainWindow와 연결하기 위해 HelloiPhone2AppDelegate.h 파일을 열어 다음을 추가 코딩 합니다.

/*HelloiPhone2AppDelegate.h*/
#import <UIKit/UIKit.h>
//생성된 클래스 선언 #import "HelloiPhoneViewController.h" 를 선언도 동일함
@class HelloiPhoneViewController;

@interface HelloiPhone2AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    //추가된 클래스의 객체를 선언
    HelloiPhoneViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
//객체생성(메모리 할당)
@property (nonatomic, retain) IBOutlet HelloiPhoneViewController *viewController;
@end

=====================
/*HelloiPhone2AppDelegate.m*/

#import "HelloiPhone2AppDelegate.h"
//헤더 부분에 import를 하지 않고 class 선언을 했을 경우 바디 파일에서 꼭 import 선언
#import "HelloiPhoneViewController.h"

@implementation HelloiPhone2AppDelegate

@synthesize window;
//get, set 사용을 위한 synthesize 선언
@synthesize viewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // Override point for customization after application launch
    // 메인윈도우에 view추가
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}
- (void)dealloc {
    [window release];
    //메모리 해제
    [viewController release];
    [super dealloc];
}
@end

4. HelloiPhoneViewController.xib 파일을 만들어 보겠습니다. cmd+n을 누릅니다.
새 파일 생성에서 좌측 User Interface 클릭 후 view xib를 선택 합니다.
xib 파일은 모두 생성이 완료 되었습니다.. 이제 xib와 생성한 controller 클래스간의 연결을 해봅시다.
먼저 MainWindow.xib를 연결해 보겠습니다. 처음 coontroller 클래스를 생성시 wiith xib for user interface 체크를 선택 하고 controller 클래스를 생성 하였다면 MainWindow.xib의 연결 설정을 할 필요는 없지만.. 이번에는 선택을 하지 않고 생성 하였기 때문에 우선 서로 연결을 해봅니다.
MainWindow.xib를 더블클릭으로 IB를 실행 시킵니다. 아래와 같이 Window.xib 창에는 어떠한 View Controller가 포함 되어 있지 않네요..



우선 Window 창에 View Controller를 추가 해보겠습니다. Library 에서 View Controller를 선택 합니다.
(노랑 바탕의 View입니다 흰바탕의  View와 혼동하지 마시길 바랍니다.) 드래그를 하여 File's Onewr/First Responder/... 등의 내용이 보이는 MainWindow.xib 윈도우 창에 View Controller를 놓습니다. 그럼 아래와 같이 하나의 View Controller 창이 새로 생성이 됩니다... 자 이제 연결을 해봅시다.



먼저 View Controller를 선택하고 Inspector(아래의 창입니다) 에서 cmd+1을 누릅니다. 그러면 속성 창으로 탭이 변경됩니다. (Inspector 창의 각 탭은  cmd+1..2..3..4로 탭창이 변경 가능 합니다.)
아래와 같이 nib name을 HelloiPhonViewController로 변경 합니다.



 그리고 cmd+4를 눌러 Identy Inspector 탭을 엽니다 4번째 탭... 여기서 Class를 HelloiPhoneViewController로 변경 합니다.



다음은 Hello iPhone2 AppDelegate를 선택하여 아래의 그림과 같이 연결을 합니다. Hello iPhone2 AppDelegate 의 연결이 완료 되면  HelloiPhoneController 에도 연결된 내용이 등록됩니다.





5. 자.. 마지막으로 HelloiPhoneViewController.xib 파일을 편집해보겠습니다..
먼저..HelloiPhoneViewController.xib를 더블클릭 해서 IB에 로드합니다.
View에 라벨을 올리고 Hello, iPhone 이라고 디자인을 합니다.
그리고 File's Owner를 클릭 Identy Inspector창을 띄웁니다(cmd+4) 그리고 class 를 HelloiPhoneViewController로 변경합니다.



그리고 File's Owner의 Connection을 연결합니다.



그러면 자동으로 View에도 Connection이 등록 됩니다.



자 이제 Build & Run 을 실행... 동일한 결과를 보실 수 있어요 ^^



수고 하셨습니다..  곰곰히 생각해보세요 흐름을...
중요한 것은 Connnection을 하기전 해당 클래스를 사용자가 추가한 클래스로 변경 한다는 것입니다. 
MainWindow의 경우는 nib name도 같이 변경을 해야 합니다..

잘되지 않을 경우 xcodenine@G메일.컴 으로 연락 주세요
ㅋㅋㅋ 자세히 설명 드릴께요...

정말 수고하셨어요 ^^ 다음 스터디 내용은
여러개의 뷰에 대한 스위칭 입니다. 시간이되면 툴바 및 텝바에 대해서도 진행 합니다.
다음 스터디에 뵙겠습니다.




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

댓글을 달아 주세요