최초 작성일 : 2010/04/11 09:00


사용된 메서드 정리


메서드명 : - (NSArray *)componentsSeparatedByString:(NSString *) separator

기능 : separator 구분자로 하여 분리된 배열을 반환함

선언된 클래스 : NSString


메서드명 : + (NSArray *)knownTimeZoneNames:

기능 시스템이 알고있는 모든 time zone의 ID를 문자열 배열로 반환함

선언된 클래스 : NSTimeZone


메서드명 : + (id)timeZoneWithName:(NSString *)aTimeZoneNZme

기능 : 인자로 넘어온 ID와 일치하는 time zone 객체를 반환

선언된 클래스 : NSTimeZone


메서드명 : - (id)initWithKey:(NSString *)keyPath ascending:(BOOL)ascending

기능 : 인자로 넘어온 key path를 정렬기준으로 역시 인자로 넘어온 정렬 순서를 적용하고

   기본 비교 selector를 통해 초기화된 NSSortDescriptor 객체를 반환한다.


          ascending인자가 YES이면 오름차순 NO이면 내림차순 정렬한다.

선언된 클래스 : NSSortDescriptor


메서드명 : - (id)initWithObject:(const id *)object count:(NSUInteger)count

기능 : 인자로 넘어온 C array로부터 count 갯수만큼의 객체를 뽑아 포함시키는 새로운 배열을 할당함

언된 클래스 : NSArray 클래스


메서드명 : -(void)sortUsingDescriptor:(NSArray *)sortDescriptors

기능 : 인자로 넘어온 NSSortDescriptor 객체의 배열을 사용하여 배열을 정렬함.

선언된 클래스 : NSMutableArray


블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/04/10 16:06 



SimpleSectionedTableView 추가된 내용  하나는 Model 클래스가 추가되었다는점이다.

Model Object 데이터를 캡슐화 하는 핵심적인 역할을 하고 있으며  데이터 접근할 있는

접근자를 제공한다모델 클래스들은 전통적인 행동 방식(getter 이용하는 ?) 내에서 값을 추가할  있다.

Region 클래스는 시스템으로부터 시스템이 알고있는 TimeZone 정보를 가져와
지역 이름을 추출하여 Region 인스턴스들이 담긴 regions 배열을 만들고
regions 배열에 담긴 각각의 Region 인스턴스에 있는 TimeZoneWrappers라는 
인스턴스 배열 변수에 TimeZoneWrapper 클래스의 인스턴스를 설정하여
넣는다.

전체적인 구조는 Region 클래스는 지역 이름을 담당하여 지역 이름의 배열을 만들고
TimeZoneWrapper 클래스는 Time Zone 관련 데이터를 담당하여 각각의
Region 클래스의 인스턴스 안에 역시 배열로 들어간다.

regions[0]
timeZoneWrappers[0]
timeZoneWrappers[1]
timeZoneWrappers[2]
...
regions[1]
timeZoneWrappers[0]
timeZoneWrappers[1]
...
regions[2]
timeZoneWrappers[0]
timeZoneWrappers[1]
...
...

regions[0], regions[1], regions[2]는 각각 Region 클래스의 인스턴스이고
timeZoneWrappers[i]는 각각 TimeZoneWrapper 클래스의 인스턴스들이다.


Region.h


@interface Region : NSObject {

NSString *name;

NSMutableArray *timeZoneWrappers;

}

//@property 이용하여 getter setter 선언 자동화

//@property 속성으로 copy 지정된 경우얕은 복사가 일어난다.

//얕은 복사는 원본 데이터가 담겨있는 메모리의 주소만을 복사하여  변수에

//넘기고 원본의 주소는 release 되는 형태로 복사가 이루어진다고 하여 실제로

//데이터가 2개가 되는 것은 아니다.

@property (nonatomiccopy) NSString *name;

@property (nonatomicretain) NSMutableArray *timeZoneWrappers;

//클래스 메서드의 선언앞에 + 기호로 시작하는 메서드는 클래스 메서드로

//주로 클래스의 인스턴스를 생성하거나 글로벌 클래스 데이터에 접근하는 역할을 하며

//java static 선언과 유사하다고 생각하면 된다.

//반대로 -기호로 시작하는 메서드는 인스턴스 메서드이며 인스턴스 메서드는 클래스의

//인스턴스와  생명 주기를 함께 한다.

+ (NSArray *)knownRegions;

@end




Region.m

지역과 지역별 Time Zone 데이터를 설정하고 정렬하는 Model 클래스


//헤더파일 임포트

#import "Region.h"

#import "TimeZoneWrapper.h"

//카테고리 선언 : Private라는 이름으로 Region 클래스에 카테고리를 선언함

@interface Region (Private)

- (id)initWithName:(NSString *)regionName;

//setUpKnownRegions 메서드는 클래스 메서드로 선언도어 있으므로 인스턴스 생성 없이

//클래스로부터 바로 호출할  있다.

+ (void)setUpKnownRegions;

- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper;

- (void)sortTimeZones;

@end


@implementation Region

//@property 키워드와 함께 name, timeZoneWrapper 대한 getter setter 자동으로 구현한다.

@synthesize name, timeZoneWrappers;

//클래스 메서드인 setUpKnownRegions 통해 값을 설정할  있도록 static으로 선언된 변수

static NSMutableArray *knownRegions = nil;

//클래스 메서드인 knownRegions 내부에서 카테고리를 통해 선언된 클래스 메서드인

//setUpKnownRegions 메서드를 호출한다  사용된 self Region 클래스를 의미한다.

+ (NSArray *)knownRegions {

if (knownRegions == nil) {

[self setUpKnownRegions];

}

return knownRegions;

}

#pragma mark -

#pragma mark Memory management.

//메모리 해제...

- (void)dealloc {

//copy 생성된 것에 대한 메모리 해제

[name release];

[timeZoneWrappers release];

[super dealloc];

}

#pragma mark -

#pragma mark Private methods for setting up the regions.

//카테고리를 통해 선언된 메서드의 구현인자로 받은 regionName 통해 호출되는 copy

//NSObject 구현되어있으며  copy 메서드는 NSCopying 적용된 subclass에서

//copyWithZone 함수를 호출하는 방식으로 동작한다. NSCopying 프로토콜은 NSString

//적용 되어 있다.

//copy 새로운 인스턴스 변수에 원본의 주소값을 복사한  retain count 1 증가 시키므로

//release 통해 메모리 해제를 해주어야 한다.  

- (id)initWithName:(NSString *)regionName {

if (self = [super init]) {

name = [regionName copy];

timeZoneWrappers = [[NSMutableArray allocinit];

}

return self;

}

//클래스 메서드인 setUpKnownRegions 구현

+ (void)setUpKnownRegions {

//시스템으로부터 확인된 TimeZone 이름 배열을 가져오고  배열의 크기와 동일하게

//변경 가능한 배열인 regions 만든다.

NSArray *knownTimeZoneNames = [NSTimeZone knownTimeZoneNames];

NSMutableArray *regions = [[NSMutableArray allocinitWithCapacity:[knownTimeZoneNames count]];

//knownTimeZoneNames 크기만큼 루프를 돌면서 배열  하나 하나를 timeZoneName 넣는다.

for (NSString *timeZoneName in knownTimeZoneNames) {

//knownTimeZoneNames로부터 받은 문자열을 "/" 구분자로 나누어

//배열 nameComponents 담는다.

NSArray *nameComponents = [timeZoneName componentsSeparatedByString:@"/"];

//배열 nameComponents 0번째 값을 가져와 regionName 할당한다.

NSString *regionName = [nameComponents objectAtIndex:0];

// Get the region  with the region name, or create it if it doesn't exist.

Region *region = nil;

//for문을 통해 regions 배열의  하나 하나를 Region 인스턴스인 aRegion 할당한다.

for (Region *aRegion in regions) {

//regions로부터 받아온 값의 name 속성이 regionName 같다면

//region aRegion 할당하고 루프를 빠져나옴

if ([aRegion.name isEqualToString:regionName]) {

region = aRegion;

break;

}

}

//만일 name 일치하는 경우가 없다면 regionName 사용하여 새로운 region 만들어

//regions 추가한다.

if (region == nil) {

region = [[Region allocinitWithName:regionName];

[regions addObject:region];

[region release];

}

//timeZoneName 사용하여 NSTimeZone 인스턴스인 timeZone 생성하고

NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];

//생성된 timeZone timeZoneName 배열로 만든 nameComponents 인자로

//TimeZoneWrapper 인스턴스를 생성한다.

TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper allocinitWithTimeZone:timeZonenameComponents:nameComponents];

//생성된 timeZoneWrapper NSMutableArray timeZoneWrappers 넣는다.

[region addTimeZoneWrapper:timeZoneWrapper];

//alloc으로 생성했으므로 메모리 해제

[timeZoneWrapper release];

}

// Now sort the time zones by name

//카테고리를 통해 추가된 함수를 호출하여 이름순으로 정렬

for (Region *aRegion in regions) {

[aRegion sortTimeZones];

}

// Sort the regions

//지역(region) 정렬

//"name" 속성을 기준으로 오름차순 정렬을  것임을 NSSortDescriptor클래스의 인스턴스를 통해 설정

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor allocinitWithKey:@"name" ascending:YES];

//initWithObjects 인자로 넘겨받은 C 배열로부터 count 인자로 넘겨받은 수만큼의(여기서는 1객체를

//가져와 새롭게 배열로 할당한다.

NSArray *sortDescriptors = [[NSArray allocinitWithObjects:&sortDescriptor count:1];

//sortDescriptors 이용해 실제로 배열을 정렬한다.

[regions sortUsingDescriptors:sortDescriptors];

[sortDescriptor release];

[sortDescriptors release];

knownRegions = regions;

}

//인자로 받은 timeZoneWrapper NSMutableArray timeZoneWrappers 넣는다.

- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper {

[timeZoneWrappers addObject:timeZoneWrapper];

}

- (void)sortTimeZones {

// Sort the time zones by name

//time zones 정렬 - 상세 과정은 위의 지역 정렬 참조

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor allocinitWithKey:@"localeName"ascending:YES];

NSArray *sortDescriptors = [[NSArray allocinitWithObjects:&sortDescriptor count:1];

[timeZoneWrappers sortUsingDescriptors:sortDescriptors];

[sortDescriptor release];

[sortDescriptors release];

}

@end




TimeZoneWrapper.h


//TimeZoneWrapper 인터페이스

@interface TimeZoneWrapper : NSObject {

NSString *localeName;

NSTimeZone *timeZone;

}

//지역 이름과 time zone 설정을 위한 인스턴스 변수 선언  getter/setter 선언

@property (nonatomiccopy) NSString *localeName;

@property (nonatomicretain) NSTimeZone *timeZone;

//초기화를 위한 인스턴스 메서드 선언

- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents;

@end



TimeZoneWrapper.m


#import "TimeZoneWrapper.h"



@implementation TimeZoneWrapper

//인스턴스 변수들에 대한 getter/setter 구현

@synthesize localeName, timeZone;


- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray*)nameComponents {

if (self = [super init]) {

//retain 통해 인스턴스 할당. retain 인스턴스 자신을 반환하며 참조 카운트를 1 증가 시킨다.

//인스턴스의 사용이 종료되기 전까지 메모리에서 해제하는 것을 막는다따라서 사용 후에 반드시

//적절한 시점에서 release 해주어야 한다.

timeZone = [aTimeZone retain];

NSString *name = nil;

//인자로 넘어온 nameComponents 배열의 크기가 2인경우 nameComponents 

//인덱스 1 있는 값을 retain 통해 name으로 할당한다.

if ([nameComponents count] == 2) {

name = [[nameComponents objectAtIndex:1retain];

}

else {

//그렇지 않은 경우 인덱스 2 값과 인덱스 1 값을 조합하여 name 할당한다.

name = [[NSString allocinitWithFormat:@"%@ (%@)", [nameComponentsobjectAtIndex:2], [nameComponents objectAtIndex:1]];

}

//name 문자열에서 "_" 모두 " " 바꾸어 localeName 할당한다.

localeName = [[name stringByReplacingOccurrencesOfString:@"_"withString:@" "retain];

[name release];

}

return self;

}


//메모리 해제

- (void)dealloc {

[localeName release];

[timeZone release];

[super dealloc];

}



@end


블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/04/10 07:19 


xcode의 Groups&Files 창에 보여지는 소스 목록


SimpleTableView와 크게 달라진 것은 Model 클래스들이 분리되었다는 것이다.




main.m과 SimpleSectionedTavleView_Prefix.pch는 앞의 SimpleTableView와
동일하므로 분석을 생략함.

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/04/10 06:24 


인터페이스는 단순히 윈도우 위에 TableView를 얹은 정도이므로

인터페이스 빌더상에 별다른 설정은 없다.












블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/03/28 08:38



RootViewController.h


//UITableViewController를 상속받은 RootViewController 선언

@interface RootViewController : UITableViewController {

//클래스 변수로 NSArray 타입의 timeZoneNames선언

NSArray *timeZoneNames;

}


//접근자와 변경자 자동 선언 키워드

@property (nonatomicretain) NSArray *timeZoneNames;


@end




RootViewController.m

//선언부 import

#import "RootViewController.h"

#import "SimpleTableViewAppDelegate.h"



@implementation RootViewController

//접근자와 변경자 자동 구현 키워드

@synthesize timeZoneNames;


//UIViewController에 있는 함수. 메모리에 컨트롤러의 뷰가 로드된 후 호출됨

- (void)viewDidLoad {

     //title은 UIViewController에 있는 속성

   //NSLocalizedString : Foundation Function. NSBundle에 있는

     //localizedStringForKey:value:table: 함수를 실행시켜

  //지역화된 문자열을 반환Time Zones라는 테이블로부터

     //Time Zones title이라는 값을 가져온다.

self.title = NSLocalizedString(@"Time Zones"@"Time Zones title");

}


//UITableView에 구현된 UITableViewDataSource protocol에 있는 함수. 

//테이블 뷰에 섹션이 몇개 있는지 갯수를 반환

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

// There is only one section.

return 1;

}



//UITableView에 구현된 UITableViewDataSource protocol에 있는 함수. 

//인자로 넘어간 테이블 뷰 내의 섹션에 몇개의 row가 있는지를 반환

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

// Return the number of time zone names.

//timeZoneNames배열의 내용이 그대로 테이블 뷰를 구성하므로 그 크기를 반환함

return [timeZoneNames count];

}


//UITableView에 구현된 UITableViewDataSource protocol에 있는 함수. 

//인자로 넘어간 테이블 뷰의 특정 위치(인자로 넘어간 indexPath)에 cell을 삽입하는 함수.

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

static NSString *MyIdentifier = @"MyIdentifier";

// Try to retrieve from the table view a now-unused cell with the given identifier.

//인자로 넘어간 문자열을 이름으로 갖는 재사용 가능한 테이블 뷰 셀을 반환.

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];

// If no cell is available, create a new one using the given identifier.

//만일 재사용 가능한 셀이 없으면 새로운 셀을 생성

if (cell == nil) {

// Use the default cell style.

//alloc으로 생성하였으므로 반드시 release해주어야 함. 그러나 cell은 다른 위치에서 참조되고 사용되므로

//autorelease를 설정하여 처리함

//UITableViewCellStyleDefault라는 셀 스타일과 MyIdentifier라는 식별자로 셀을 초기화 함

cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleDefaultreuseIdentifier:MyIdentifier] autorelease];

}

// Set up the cell.

//timeZoneNames 배열의 인자로 받은 위치에 있는 문자열을 추출하고

NSString *timeZoneName = [timeZoneNames objectAtIndex:indexPath.row];

//추출한 문자열을 셀의 text 속성에 넣는다.

cell.textLabel.text = timeZoneName;

return cell;

}


/*

 To conform to Human Interface Guildelines, since selecting a row would have no effect (such as navigation), make sure that rows cannot be selected.

 */

//인자로 받은 tableView의 indexPath위치에 있는 cell이 선택되었음을 delegate에게 전달한다.

//이 예제에서는 cell 선택에 대한 내용을 처리하지 않으므로 그냥 nil을 리턴한다.

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

return nil;

}


//메모리 해제

- (void)dealloc {

[timeZoneNames release];

[super dealloc];

}


@end


[Notice]
UITableView는 2개의 protocol을 구현하고 있는데
UITableViewDelegate는 테이블 뷰의 설정을 처리혹
UITableViewDataSource는 테이블 뷰의 각 행의 데이터를 처리한다.

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/03/27 09:00 



SimpleTableViewAppDelegate.h

//애플리케이션의 delegate 클래스 NSObject를 상속받고 있으며

//UIApplicationDelegate 프로토콜을 구현한다.

@interface SimpleTableViewAppDelegate : NSObject <UIApplicationDelegate> {

//인스턴스 변수 선언

UIWindow *window;


//계층적 데이터간에 이동을 표현할 수 있도록 해주는 뷰 컨트롤러 클래스

UINavigationController *navigationController;

}


//접근자와 변경자를 자동 생성하도록 해주는 @property 키워드 선언

@property (nonatomicretainIBOutlet UIWindow *window;

@property (nonatomicretain) UINavigationController *navigationController;


@end




SimpleTableViewAppDelegate.m



//필요한 헤더파일들 import

#import "SimpleTableViewAppDelegate.h"

#import "RootViewController.h"


@implementation SimpleTableViewAppDelegate


//헤더파일의 @property 키워드와 조합되어 접근자 및 변경자를 자동 생성시켜줌

@synthesize window;

@synthesize navigationController;


//UIApplicationDelegate프로토콜에 선언된 함수

//애플리케이션 시작되었음을 delegate에게 알려주는 함수. 인자는 시작된 애플리케이션 객체

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

/*

Create and configure the navigation and view controllers.

뷰 컨트롤러의 인스턴스 생성. alloc으로 생성되었으므로 후에 release 필요

*/


RootViewController *rootViewController =

[[RootViewController allocinitWithStyle:UITableViewStylePlain];

// Retrieve the array of known time zone names, 

// then sort the array and pass it to the root view controller.

//time zone이름 목록을 가져와 배열에 담는다.

NSArray *timeZones = [NSTimeZone knownTimeZoneNames];


//localizedCaseInsensitiveCompare : NSString 함수. 인자로 들어오는 문자열에

        //대/소문자 구분 안함, 지역화함, 비교대상임을  표시하여 리턴한다.

//@selector : 특정 함수 이름을 인자로 받아 다른 객체 내에서 그 함수가 실행되도록 한다.

//현재 코드에서는 NSString 클래스의 함수인 localizedCaseInsensitiveCompare를 @selector를 통해

//NSArray의 인스턴스인 timeZones의 함수 sortedArrayUsingSelector가 배열 값들을 정렬한는데

//사용할 수 있도록 해준다.

//즉, sortedArrayUsingSelector 함수는 localizedCaseInsensitiveCompare 함수를 이용하여

//배열 값들을 정렬한다.

//sortedArrayUsingSelector : NSArray 클래스의 함수. selector를 통헤 재공되는 특정 비교 방식을 사용하여

//정렬된 배열을 리턴하는 함수

rootViewController.timeZoneNames = [timeZonessortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

//네비게이션 뷰 컨트롤러 생성 역시 alloc을 통해 생성하였으므로 반드시 release해주어야 한다.

//initWithRootViewController : 새로 생성된 네비게이션 컨트롤러를 초기화 하여 반환한다. 

//인자는 네비게이션 스택의 가장 하부(가장 앞)에 존재하는 뷰 컨트롤러임.

UINavigationController *aNavigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];

self.navigationController = aNavigationController;

//alloc으로 생성한 인스턴스들 release

[aNavigationController release];

[rootViewController release];


// Configure and display the window.

//윈도우에 뷰를 추가하고 화면에 출력한다.

//addSubview : UIView클래스의 함수. receiver의 서브 뷰로 뷰를 추가하고 제일 위에 보여지도록 한다.

//makeKeyAndVisible : UIWindow클래스의 함수. 해당 윈도우를 가장 앞에서 사용자의 입력을 받는

        //key window로 만들고 이것을 화면에 출력한다.

[window addSubview:[navigationController view]];

[window makeKeyAndVisible];

}


//메모리 해제

- (void)dealloc {

[navigationController release];

    [window release];

    [super dealloc];

}

@end


블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/03/21 08:53


### TableViewSuite ###

================================================================================
DESCRIPTION:

This sample shows how to use UITableView through a progression of increasingly 
advanced applications that display information about time zones.

이 예제는 time zones에 관한 정보를 출력하는 점차로 개선되는 애플리케이션을 통해 
UITableView의 사용법을 보여준다.

* The first example shows a simple list of the time zone names. 
It shows how to display a simple data set in a table view.

첫 예제는 time zone 이름의 목록을 화면에 출력한다.
이것은 간단한 데이터 셋을 테이블 뷰에 표시하는 방법을 보여준다.

* The second example shows the time zones split into sections by region, 
with the region name as the section heading. It shows how to create an indexed table view.

두 번 째 예제는 분리된 각각의 영역에서 time zone의 목록을 보여주며 각 지역의 이름이 그 영역의
머릿말로 표시된다. 이것은 indexed table view를 생성하는 방법을 보여준다.

* The third example shows how to set up a table view to display an index. 
The time zones are separated into sections using UILocalizedIndexedCollation.

세 번 째 예제는 인덱스를 보여주기 위해 테이블 뷰를 설정하는 방법을 보여준다.
time zone들은 UILocalizedIndexedCollation을 통해 분리된 영역에 들어가게 된다.


When implementing a table view cell, there's a tension between optimal scrolling performance 
and optimal edit/reordering performance. 
You should typically use subviews in the cell's content view.

테이블 뷰 셀을 구현할 때 최적의 스크롤 성능과 최적의 편집/재정렬 성능사이에 주의를 기울여야 한다.
일반적으로 셀들의 컨텐트 뷰 안에 서브뷰를 사용하게 된다.

When you have an edit or reordering control, using subviews makes the implementation easier, 
and the animations perform better because UIKit doesn't have to redraw during animations.

편집 또는 재정렬 컨트롤을 가지고 작업을 할 때 서브뷰를 이용하는 것이 구현을 보다 쉽게해주며 UIKit이 애니메이션
진행 동안 다시 그리는 작업을 하지 않기 때문에 애니메이션의 성능도 더 좋아진다.

Subviews have two costs:
1) Initialization. This can be largely mitigated by reusing table cells.
2) Compositing. This can be largely mitigated by making the views opaque. 
Often, one translucent subview is fine, but more than one frequently 
causes frame drops while scrolling.

서브뷰들은 다음과 같은 2가지 작업을 필요로 한다:
1) 초기화. 이 작업은 테이블 셀들의 재사용을 통해 작업을 크게 경감할 수 있다.
2) 구성. 이 작업은 뷰를 불투명하게 만듦으로써 작업을 크게 경감할 수 있다.
때때로 반투명한 서브뷰는 보기에는 좋지만 자주 스크롤 되는 동안 프레임이 저하되는 원인이 되곤 한다. 

If the content is complex, however (more than about three subviews), scrolling performance may suffer. 
If this becomes a problem, you can instead draw directly in a subview of the table view cell's content view.

만일 내용이 될 데이터가 복잡한데다 3개 이상의 서브뷰를 사용하게 되면 스크로 성능은 많이 저하될 것이다.
만일 문제가 발생할 경우 셀의 컨텐트 뷰에 테이블 뷰의 서브 뷰를 직접 그리는 것이 좋을 것이다.


* The fourth example displays more information about each time zone, such as the time and 
relative day in that time zone. 
Its main aim is to show how you can customize a table view cell using subviews. 
It also introduces custom classes to represent regions and time zones to help reduce 
the overhead of calculating the required information -- these are also used in the fifth example.

네 번 째 예제는 각각의 time zone에 대해 시간,  해당 time zone에서의 상대적인 시간 등 추가적인 정보를 화면에 출력한다. 
이 예제의 중요 목표는 서브뷰를 이용하여 테이블 뷰 셀을 어떻게 커스터마이징 할 수 있는가 하는 것이다.
또한 지역과 time zone들을 표현하는 커스텀 클래스가 필요한 정보를 연산하는데 부하를 줄이도록 도와주는 방법을 소개할 것이다.
이 예는 다섯 번 째 예제에서도 사용된다.

* The fifth example is an extension of the fourth. It displays even more information 
about each time zone, such as the time and relative day in that time zone. 
Its shows how you can create a custom table view cell that contains a custom view 
that draws its content in -drawRect:.

다섯 번 째 예제는 네 번 째 예제의 확장이다. 이 예제는 각각의 time zone에 대해 시간이나 해당 time zone내의
상대적인 시간과 같은 보다 많은 정보를 화면에 출력한다. 
이 예제는 -drawRect:함수를 통해 내용 데이터를 그리는 커스텀 뷰를 포함하는 커스텀 테이블 뷰 셀을 생성하는 방법을
보여준다.



================================================================================
BUILD REQUIREMENTS:

Mac OS X 10.5.7, Xcode 3.2, iPhone OS 3.0

================================================================================
RUNTIME REQUIREMENTS:

Mac OS X 10.5.7, iPhone OS 3.0

================================================================================
PACKAGING LIST:


1_SimpleTableView
-----------------
1_SimpleTableView/Classes/RootViewController.{h,m}
View controller that sets up the table view and serves as the table view's data source and delegate.

테이블 뷰를 설정하고 테이블 뷰의 데이터와 위임을 제공하는 뷰 컨트롤러

1_SimpleTableView/Classes/SimpleTableViewAppDelegate.{h,m}
Application delegate that configures the view controller.

뷰 컨트롤러를 설정하는 애플리케이션의 delegate 클래스

1_SimpleTableView/MainWindow.xib
The xib file containing the application's main window.

애플리케이션의 메인 윈도우를 포함하는 xib 파일

1_SimpleTableView/en.lproj/Localizable.strings
Strings file containing localization dictionary.

지역화 사전을 포함하는 문자열들의 파일



2_SimpleSectionedTableView
--------------------------
2_SimpleSectionedTableView/Classes/RootViewController.{h,m}
View controller that serves as the table view's data source and delegate. It also set up the data.

테이블 뷰의 데이터와 위임을 제공하는 뷰 컨트롤러로 데이터 설정도 수행함

2_SimpleSectionedTableView/Classes/SimpleSectionedTableViewAppDelegate.{h,m}
Application delegate that configures the view controller.

뷰 컨트롤러를 설정하는 애플리케이션의 delegate 클래스

2_SimpleSectionedTableView/Classes/Region.{h,m}
Object to represent a region containing the corresponding time zone wrappers.

time zone wrappers에 해당하는 지역 정보를 함께 보여주는 객체

2_SimpleSectionedTableView/Classes/TimeZoneWrapper.{h,m}
Object to represent a time zone, caching various derived properties that are expensive to compute.

time zone을 표현하는 객체로 연산하기 까다로운 다양한 파생 속성들을 저장한다.

2_SimpleSectionedTableView/MainWindow.xib
The xib file containing the application's main window.

애플리케이션의 메인 윈도우를 포함하는 xib 파일

2_SimpleSectionedTableView/en.lproj/Localizable.strings
Strings file containing localization dictionary.

지역화 사전을 포함하는 문자열들의 파일


3_SimpleIndexedTableView
------------------------
3_SimpleIndexedTableView/Classes/RootViewController.{h,m}
View controller that serves as the table view's data source and delegate. 
It uses the current UILocalizedIndexedCollation object to organize 
the time zones into appropriate sections, and also to provide information 
about section titles and section index titles.

테이블 뷰의 데이터와 위임을 제공하는 뷰 컨트롤러.
time zone들을 적절한 섹션에 정리하기 위해 UILocalizedIndexedCollation 객체를 사용하며
영역 제목과 인덱스 제목에 관련된 정보들 또한 제공한다.


3_SimpleIndexedTableView/Classes/SimpleIndexedTableViewAppDelegate..{h,m}
Application delegate that configures the view controller.

뷰 컨트롤러를 설정하는 애플리케이션의 delegate 클래스

3_SimpleIndexedTableView/Classes/TimeZoneWrapper.{h,m}
Object to represent a time zone, caching various derived properties that are expensive to compute.

time zone을 표현하는 객체로 연산하기 까다로운 다양한 파생 속성들을 저장한다.

3_SimpleIndexedTableView/MainWindow.xib
The xib file containing the application's main window.

애플리케이션의 메인 윈도우를 포함하는 xib 파일

3_SimpleIndexedTableView/en.lproj/Localizable.strings
Strings file containing localization dictionary.

지역화 사전을 포함하는 문자열들의 파일


4_TableViewCellSubviews
-----------------------
4_TableViewCellSubviews/Classes/TableViewCellSubviewsAppDelegate.{h,m}
Application delegate that sets up the navigation controller and the root view controller.

네비게이션 컨트롤러와 root 뷰 컨트롤러를 설정하는 애플리케이션의 delegate

4_TableViewCellSubviews/Classes/RootViewController.{h,m}
View controller that sets up the table view and the time zone data.

테이블 뷰와 time zone 데이터를 설정하는 뷰 컨트롤러

4_TableViewCellSubviews/Classes/Region.{h,m}
Object to represent a region containing the corresponding time zone wrappers.

time zone wrappers에 해당하는 지역 정보를 함께 보여주는 객체

4_TableViewCellSubviews/Classes/TimeZoneWrapper.{h,m}
Object to represent a time zone, caching various derived properties that are expensive to compute.

time zone을 표현하는 객체로 연산하기 까다로운 다양한 파생 속성들을 저장한다.

4_TableViewCellSubviews/MainWindow.xib
The xib file containing the application's main window.

애플리케이션의 메인 윈도우를 포함하는 xib 파일

4_TableViewCellSubviews/en.lproj/Localizable.strings
Strings file containing localization dictionary.

지역화 사전을 포함하는 문자열들의 파일


5_CustomTableViewCell
---------------------
5_CustomTableViewCell/Classes/CustomTableViewCellAppDelegate.{h,m}
Application delegate that sets up the navigation controller and the root view controller.

네비게이션 컨트롤러와 root 뷰 컨트롤러를 설정하는 애플리케이션의 delegate

5_CustomTableViewCell/Classes/RootViewController.{h,m}
View controller that sets up the table view and the time zone data.

테이블 뷰와 time zone 데이터를 설정하는 뷰 컨트롤러

5_CustomTableViewCell/Classes/Region.{h,m}
Object to represent a region containing the corresponding time zone wrappers.

time zone wrappers에 해당하는 지역 정보를 함께 보여주는 객체

5_CustomTableViewCell/Classes/TimeZoneWrapper.{h,m}
Object to represent a time zone, caching various derived properties that are expensive to compute.

time zone을 표현하는 객체로 연산하기 까다로운 다양한 파생 속성들을 저장한다.

5_CustomTableViewCell/Classes/TimeZoneCell.{h,m}
A table view cell to display various pieces of information about a time zone.. 

time zone과 관련된 다양한 정보 조각들을 화면에 출력하기 위한 테이블 뷰 셀

5_CustomTableViewCell/Classes/TimeZoneView.{h,m}
A view to display various pieces of information about a time zone.

time zone과 관련된 다양한 정보를 화면에 출력하기 위한 뷰

5_CustomTableViewCell/MainWindow.xib
The xib file containing the application's main window.

애플리케이션의 메인 윈도우를 포함하는 xib 파일

5_CustomTableViewCell/en.lproj/Localizable.strings
Strings file containing localization dictionary.

지역화 사전을 포함하는 문자열들의 파일


================================================================================
CHANGES FROM PREVIOUS VERSIONS:

Version 2.0
- Corrected a memory leak in the displayMethod  in CustomTableViewCellAppDelegate.m.

Version 2.0
- Updated for and tested with iPhone OS 3.0.
- Adopted new UITableViewCell API where appropriate.
- SimpleIndexedTableView uses UILocalizedIndexedCollation.
- Application data created by the application delegate but passed to the first view controller.


Version 1.8
- Updated for and tested with iPhone OS 2.0. First public release.
- Modified fourth and fifth examples to make timer-based updates more efficient.

Version 1.7
- Modified fourth and added fifth example.

Version 1.6
- Updated the Default.png image.
- Added LSRequiresIPhoneOS flag to Info.plist files.

Version 1.5
- Updated for Beta 5.
- Added localized strings files.
- Made minor changes to project file -- added ReadMe, removed project-level override for 
ALWAYS_SEARCH_USER_PATHS, added override at target level.
- Removed Visible At Launch flag from window in MainWindow.xib; 
added [window makeKeyAndVisible] in application delegate.

Version 1.4
- Updated for Beta 4.
- Adopts the new pattern in the Cocoa Touch List project template.
- The application delegate serves as the controller for the application's data; 
the table view controllers retrieve data from the application delegate.
- Minor changes to artwork.

Version 1.3
- Updated for Beta 3.
- The samples now use nib files and UITableViewController; they also adopt the new pattern for table cell reuse.

================================================================================
Copyright (C) 2008 Apple Inc. All rights reserved.

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/03/12 09:43



MyViewController.h


#import <UIKit/UIKit.h>


//UIViewController을 상속받고

//UITextFieldDelegate 프로토콜을 따르는 뷰 컨트롤러 선언

@interface MyViewController : UIViewController <UITextFieldDelegate> {

//nib 파일 내의 객체와 연결될 인스턴스 변수 선언

//텍스트필드와 라벨과 연결됨

IBOutlet UITextField *textField;

IBOutlet UILabel *label;


//문자열 형식의 인스턴스 변수 선언

NSString *string;

}


//@property를 통한 접근자와 변경자 선언 간편화

@property (nonatomicretain) UITextField *textField;

@property (nonatomicretain) UILabel *label;

@property (nonatomiccopy) NSString *string;


//구현해야 할 메서드 선언 : 텍스트필드에서 입력받은 문자열을 라벨로 업데이트 함

- (void)updateString;


@end



MyViewController.m


#import "MyViewController.h"



@implementation MyViewController


//헤더 파일의 @property와 짝을 이루어 접근자와 변경자 자동 생성

@synthesize textField;

@synthesize label;

@synthesize string;


//뷰가 로드된 이후 호출되는 함수로 다른 nib 객체들에 대한 접근도 가능하다.

//주로 컨트롤러가 생성될 때 초기화 하는 내용이 들어감

- (void)viewDidLoad {

    // When the user starts typing, show the clear button in the text field.

  // 사용자의 키 입력이 시작되면 텍스트필드에 클리어 버튼을 보여주도록 설정

    textField.clearButtonMode = UITextFieldViewModeWhileEditing;


    // When the view first loads, display the placeholder text that's in the

    // text field in the label.

    // 뷰가 처음 로드되면 텍스트필드의 placeholder에 있는 텍스트를 라벨에 보여줌

    // placeholder는 텍스트필드에 입력된 문자열이 없을 경우 보여지게 될 기본 문자열을 저장하는

    // UITextField 클래스의 속성

    label.text = textField.placeholder;

}


//사용자 구현 메서드

//이 클래스의 인스턴스 변수인 string에 텍스트필드에 입력된 문자열을 대입하고

//다시 이 인스턴스 변수 string의 값을 label에 대입함

- (void)updateString {

// Store the text of the text field in the 'string' instance variable.

// textFeield.text는 텍스트필드에 입력받은 문자열을 저장하고 있는 UITextField 클래스의 속성

self.string = textField.text;


        // Set the text of the label to the value of the 'string' instance variable.

// label.text는 label을 통해 보여지게 될 문자열을 저장하고 있는 UILabel 클래스의 속성

label.text = self.string;

}


//UITextFieldDelegate 프로토콜에 있는 인스턴스 메서드

//텍스트필드 내에서 리턴키가 입력된 경우의 처리를 담당함

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {

// When the user presses return,

// take focus away from the text field so that the keyboard is dismissed.

// 텍스트필드에서 리턴키가 입력되면 키보드를 사라지게 하고 updateString 메서드를 호출하여

//  텍스트필드에 입력된 값을 label에 넣도록 함

if (theTextField == textField) {

[textField resignFirstResponder];


        // Invoke the method that changes the greeting.

        [self updateString];

}

return YES;

}


//UIResponder 클래스에 있는 인스턴스 메서드

//UIResponder 클래스는 객체들의 이벤트에 응답하고 이벤트를 핸들링하는 클래스로

//UIApplicationUIView 등의 클래스들의 상위 클래스이다.

//touchesBegan는 뷰나 윈도우상에 한 개 이상의 손가락 터치가 일어난 경우 이 이벤트를 받아 처리한다.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    // Dismiss the keyboard when the view outside the text field is touched.

  // 뷰에서 텍스트필드 영역 밖에 터치가 발생한 경우 키보드를 감춘다.

    [textField resignFirstResponder];


    // Revert the text field to the previous value.

  // 텍스트필드의 문자열은 이전 문자열로 바꾼다.

    textField.text = self.string;


  // 부모 클래스의 touchesBegan 메서드 호출

    [super touchesBegan:touches withEvent:event];

}


//메모리 해제

- (void)dealloc {

// To adhere to memory management rules, release the instance variables.

    // 'textField' and 'label' are objects in the nib file and are created when the nib

    // is loaded.

[textField release];

[label release];

[super dealloc];

}



@end


참고문헌 :
[시작하세요 아이폰 3 프로그래밍], 위키북스
[예제로 시작하는 아이폰 개발], 에이콘

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요

최초 작성일 : 2010/03/12 07:21



HelloWorldAppDelegate.h


//UIApplicationDelegate을 사용하기 위해 UIKit Framework를 삽입

#import <UIKit/UIKit.h>


//MyViewController 클래스를  클래스 내에서 사용하겠다는 의미

//우선은 MyViewController라는 이름의 클래스를 사용하겠다고 '예약' 해놓은

//상태로서 후에 MyViewController클래스의 구현이 변경되어도  클래스를

//재컴파일  필요가 없다.

@class MyViewController;


//HelloWorldAppDelegate 선언. NSObject를 상속 받고 있으며

//UIApplicationDelegate 프로토콜을 따른다.

@interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> {

   

    //IBOutlet은 nib(xib)파일들 안의 객체와 연결되는 인스턴스 변수임을 알려주는 키워드

    IBOutlet UIWindow *window;


    //@class에 선언된 MyViewController 클래스를 인스턴스 변수로 사용함

    MyViewController *myViewController;

}

//@property는 컴파일시에 .m파일 내의 @synthesize키워드와 결합하여

//자동으로 접근자와 변경자(getter, setter) 메서드를 생성해준다.


//retain : 메모리에 할당된 특정 객체를 객체를 참조한다는 것을 의미함

//            retain 카운트가 있어 참조되면 1이 더해지고 릴리즈되면 1이 감소하여

//            카운트가 0이되면 메모리에서 해제된다.

//            이 속성을 사용하게 되면 해당 객체는 autorelease를 사용하게 된다.

//nonatomic : 접근자와 변경자 메서드가 생성되는 방법과 관련된 키워드

               멀티쓰레드 프로그램 작성시 필요한 추가 코드를 생략할 수 있도록 해줌

               멀티쓰레드 프로그램 작성시에는 atomic으로 사용하는 것이 좋음

@property (nonatomicretain) UIWindow *window;

@property (nonatomicretain) MyViewController *myViewController;


@end



HelloWorldAppDelegate.m


//인터페이스 선언 파일 삽입

#import "HelloWorldAppDelegate.h"


//.h파일에서 @class로 선언한 MyViewController를 사용하기 위해서 헤더파일 삽입

#import "MyViewController.h"



@implementation HelloWorldAppDelegate


//헤더 파일의 @property와 짝을 이루어 자동으로 접근자와 변경자(getter, setter)메서드를

//생성해준다. 이 코드를 통해 코딩시에는 보이지 않지만 접근자인 window 라는 메서드와

//변경자인 setWindow라는 메서드가 생성된다. myViewController도 마찬가지...

@synthesize window;

@synthesize myViewController;


//어플리케이션이 모든 설정 작업을 마치고 사용자와 상호 작용할 준비를 하는 메서드

//이 메서드는 subview형태로 뷰 컨트롤러의 뷰를 애플리케이션의 메인에 붙여 사용자가

//윈도우를 볼 수 있도록 한다.

//리턴 값은 없으며 메인 애플리케이션의 객체를 인자로 받는다.

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

    // Set up the view controller

    // 뷰 컨트롤러 생성

    // nib파일의 이름인 HelloWorld와 NSBundle 객체를 인자로

    //  MyViewController의 인스턴스를 생성함

    //  NSBundle은 애플리케이션의 Root와 하위 경로들을 찾을 수 있도록 해주며

    // 해당 경로의 리소스에 접근할 수 있도록 해준다.

  MyViewController *aViewController = [[MyViewController allocinitWithNibName:@"HelloWorld" bundle:[NSBundlemainBundle]];


//인스턴스 변수 myViewController에 새로 생성한 aViewController를 대입

self.myViewController = aViewController;


//alloc을 통해 생성했으므로 release해줌

[aViewController release];

    

     // 애플의 SDK상에서 각 애플리케이션은 단 하나의 UIApplication인스턴스를 가지며

     //   그 하나의 인스턴스는

//  [UIApplication sharedApplication]을 통해 접근 가능하다.

//  [UIApplication sharedApplication]을 통해 상태 바 스타일을 지정하고 있는 코드

//  상태바 스타일은 다음 3가지 중 하나

//  UIStatusBarStyleDefault,

     // UIStatusBarStyleBlackTranslucent,

     // UIStatusBarStyleBlackOpaque

    [[UIApplication sharedApplicationsetStatusBarStyle:UIStatusBarStyleBlackOpaque];

// Add the view controller's view as a subview of the window

// myViewController를 subview로 윈도우에 붙임

UIView *controllersView = [myViewController view];

[window addSubview:controllersView];

[window makeKeyAndVisible];

}


//메모리 해제 메서드

- (void)dealloc {

[myViewController release];

[window release];

[super dealloc];

}


@end


 참고문헌 :
[시작하세요 아이폰 3 프로그래밍], 위키북스
[예제로 시작하는 아이폰 개발], 에이콘

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요