프로그래밍/Objective-C2010. 7. 21. 11:15
* CustomCell을 사용한 테이블뷰의 셀 꾸미기 예제

  - Navigation-Based Application 프로젝트 생성

  - UITableViewCell로 부터 상속받는 클래스 생성(CustomCell). Objective-C Class로 해야한다.

  - CustomCell 클래스의 헤더 파일에 변수 및 프로퍼티 선언
#import <UIKit/UIKit.h>

@interface CustomCell : UITableViewCell 
{
// 레이블 2개, 이미지 뷰 1개를 가지는 셀을 만듬.
UILabel *lblName;
UILabel *lblInfo;
UIImageView *imageView;
}

// .을 이용하기 위한 프로퍼티 선언(외부와 연결할 것이므로 IBOutlet도 지정)
@property(nonatomic,retain)IBOutlet UILabel *lblName;
@property(nonatomic,retain)IBOutlet UILabel *lblInfo;
@property(nonatomic,retain)IBOutlet UIImageView *imageView;

@end

  - CustomCell 클래스의 구현 파일(.m 파일)에 synthesize 지정
@synthesize lblName;
@synthesize lblInfo;
@synthesize imageView;

  - CustomCell의 xib 파일 추가. Resources 우클릭 > Add File > User Interface > UIView

  - 추가된 CustomCell.xib 파일을 편집(인터페이스빌더). 기본으로 붙어있는 view를 제거하고 TableViewCell을 추가

  - TableViewCell의 인스펙터 창에 있는 속성 중 ClassIdentify 부분을 위에서 만든 CustomCell 클래스로 바꿔줌
 
  - CustomCell의 화면을 디자인(이미지 뷰와 레이블 등등...). 변수연결 작업(IBOutlet)

  - RootViewController.h 파일에 데이터 변수 선언
#import <UIKit/UIKit.h>

@class CustomCellAppDelegate;

@interface RootViewController : UITableViewController 
{
NSMutableArray * ar; // 테이블 뷰에 출력될 데이터 배열
CustomCellAppDelegate * app;
}

@property(nonatomic, retain) NSMutableArray * ar;

@end

  - RootViewController.m 파일에 헤더 파일 import 시키고 synthesize 지정
#import "RootViewController.h"
#import "CustomCell.h"; // 만들어진 Custom 클래스를 사용하기 위해서 import함
#import "CustomCellAppDelegate.h";

@implementation RootViewController

@synthesize ar;

  - RootViewController.m 파일의 viewDidLoad 에서 데이터 생성
-(void)viewDidLoad
{
[super viewDidLoad];
app = (CustomCellAppDelegate *) [[UIApplication sharedApplication]delegate];

// 딕셔너리는 항상 데이터(object)와 키가 함께 저장된다. 
        //아래 Name, imageName, Description 부분이 키이다. 
// 딕셔너리 내부의 데이터에 바로 접근할 수는 없고, 항상 그 딕셔너리의 키를 통해서 접근해야만 한다.
// -(id)ObjectForKey : (id)Key -> Key에 해당하는 Object 리턴
// -(NSArray *)allKeys -> 모든 key값을 리턴

NSDictionary *dic1 = [[NSDictionary alloc] initWithObjectsAndKeys:
@"아크로뱃", @"Name", @"Acrobat.png", @"imageName", @"문서 작성", @"Description", nil];
NSDictionary *dic2 = [[NSDictionary alloc] initWithObjectsAndKeys:
@"AIM", @"Name", @"AIM.png", @"imageName", @"기본", @"Description", nil];
NSDictionary *dic3 = [[NSDictionary alloc] initWithObjectsAndKeys:
@"앱스토어", @"Name", @"AppStore.png", @"imageName", @"앱스토어", @"Description", nil];
NSDictionary *dic4 = [[NSDictionary alloc] initWithObjectsAndKeys:
@"계산기", @"Name", @"Calculator.png", @"imageName", @"계산기", @"Description", nil];

app.ar = [[NSMutableArray alloc] initWithObjects:dic1, dic2, dic3, dic4, nil];

[dic1 release];
[dic2 release];
[dic3 release];
[dic4 release];
}

  - RootViewController.m 파일에 데이터 출력
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [app.ar count];
}

// 셀을 만들어주는 메소드. indexPath는 row와 section을 멤버로 가져서 그것으로 그룹과 행을 구분한다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell"; // 셀을 구분하기 위한 문자열을 생성
    
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
 // CustomCell의 xib파일에 있는 내용을 객체로 만들어달라고 요청하는 부분
cell = (CustomCell *)[nib objectAtIndex:0]; // 배열의 첫번째 객체를 CustomCell * 으로 
                                                               // 변경해서 cell에 대입
}
NSDictionary *Dic = [app.ar objectAtIndex:indexPath.row]; // ar 배열로부터 행번호에 해당하는 
                                                                          // 딕셔너리를 Dic에 대입
cell.lblName.text = [Dic objectForKey:@"Name"];
cell.lblInfo.text = [Dic objectForKey:@"Description"];
cell.imageView.image = [UIImage imageNamed:[Dic objectForKey:@"imageName"]];
return cell;
}

// 행의 높이를 만들어주는 메소드
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}


* 인덱스 테이블 예제

1. Navigation Based Application 프로젝트 생성

2. UITableViewController로 부터 상속받는 SubViewController 추가

3. RootViewController.h  파일에 변수 선언 및 프로퍼티 선언
#import <UIKit/UIKit.h>

@class SubViewController;

@interface RootViewController : UITableViewController 
{
NSMutableArray * data; // 실제 데이터를 저장하고 있을 배열
SubViewController * subView; // 서브 데이터를 출력해 줄 서브 뷰 컨트롤러
}

@property(nonatomic, retain) NSMutableArray * data;
@property(nonatomic, retain)SubViewController * subView;

@end

4. RootViewController.m  파일에 synthesize이용과 loadview에서 데이터 생성
#import "RootViewController.h"
#import "SubViewController.h"

@implementation RootViewController

@synthesize data;
@synthesize subView;

- (void)loadView 
{
[super loadView];
NSArray *KIA;
NSArray *SK;
NSArray *HD;
NSArray *LG;
KIA = [NSArray arrayWithObjects:@"윤석민", @"이용규", @"이종범", @"김연아", @"이동국", @"박지성", @"차범근", @"허정무", nil];
SK = [NSArray arrayWithObjects:@"김광현", @"김재현", @"고효준", @"정근우", @"나주환", nil];
HD = [NSArray arrayWithObjects:@"김시진", nil];
LG = [NSArray arrayWithObjects:@"이택근", @"이병규", @"봉중근", nil];
NSDictionary *Dic1, *Dic2, *Dic3, *Dic4;
Dic1 = [[NSDictionary alloc] initWithObjectsAndKeys:@"KIA", @"Team", KIA, @"data", nil];
Dic2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"SK", @"Team", SK, @"data", nil];
Dic3 = [[NSDictionary alloc] initWithObjectsAndKeys:@"HD", @"Team", HD, @"data", nil];
Dic4 = [[NSDictionary alloc] initWithObjectsAndKeys:@"LG", @"Team", LG, @"data", nil];

self.data = [[NSArray alloc] initWithObjects:Dic1, Dic2, Dic3, Dic4, nil];

[Dic1 release];
[Dic2 release];
[Dic3 release];
[Dic4 release];
self.title = @"프로야구";
}

5. RootViewController.m  파일에 데이터를 출력하고 처리하는 메소드 작성
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    return [self.data count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    NSDictionary *Dic = [data objectAtIndex:indexPath.row];
cell.textLabel.text = [Dic objectForKey:@"Team"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if (subView == nil) 
{
SubViewController *temp= [[SubViewController alloc] initWithStyle:UITableViewStylePlain];
self.subView = temp;
[temp release];
}
self.subView.subData = [self.data objectAtIndex:indexPath.row];
[[self navigationController] pushViewController:subView animated:YES];
}

6. SubViewController.h  파일에 변수 생성과 프로퍼티 설정
#import <UIKit/UIKit.h>

@interface SubViewController : UITableViewController 
{
//루트로부터 데이터를 받을 변수
NSDictionary *subData;
//각 섹션에 해당하는 데이터
NSMutableArray *sectionData;
//인덱스 항목을 가지고 있을 변수
NSArray *index;
}

@property(nonatomic, retain)NSDictionary *subData;
@property(nonatomic, retain)NSMutableArray *sectionData;
@property(nonatomic, retain)NSArray *index;

//이름을 넘겨주면 자음을 리턴해주는 메서드
-(NSString *)subtract:(NSString *)data;
@end

7. SubViewController. m  파일에 synthesize지정과 loadView메서드 정의 
#import "SubViewController.h"

@implementation SubViewController

@synthesize subData;
@synthesize sectionData;
@synthesize index;

- (void)loadView {
[super loadView];
self.sectionData = [[NSMutableArray alloc] init];
self.index = [[NSArray alloc] initWithObjects:@"ㄱ", @"ㄴ", @"ㄷ", @"ㄹ", @"ㅁ", @"ㅂ", @"ㅅ", @"ㅇ", @"ㅈ", @"ㅊ", @"ㅋ", @"ㅌ", @"ㅍ", @"ㅎ", nil];
}

8. SubViewController. m  파일에 subtract메서드  정의
- (NSString *)subtract:(NSString*)data 
{
NSComparisonResult result = [data compare:@"나"];
if(result == NSOrderedAscending) 
return @"ㄱ";
result = [data compare:@"다"];
if(result == NSOrderedAscending) 
return @"ㄴ";
result = [data compare:@"라"];
if(result == NSOrderedAscending) 
return @"ㄷ";
result = [data compare:@"마"];
if(result == NSOrderedAscending) 
return @"ㄹ";
result = [data compare:@"바"];
if(result == NSOrderedAscending) 
return @"ㅁ";
result = [data compare:@"사"];
if(result == NSOrderedAscending) 
return @"ㅂ";
result = [data compare:@"아"];
if(result == NSOrderedAscending) 
return @"ㅅ";
result = [data compare:@"자"];
if(result == NSOrderedAscending) 
return @"ㅇ";
result = [data compare:@"차"];
if(result == NSOrderedAscending) 
return @"ㅈ";
result = [data compare:@"카"];
if(result == NSOrderedAscending) 
return @"ㅊ";
result = [data compare:@"타"];
if(result == NSOrderedAscending) 
return @"ㅋ";
result = [data compare:@"파"];
if(result == NSOrderedAscending) 
return @"ㅌ";
result = [data compare:@"하"];
if(result == NSOrderedAscending) 
return @"ㅍ";
return @"ㅎ";
}

9. SubViewController. m  파일에 viewWillAppear 메서드 재정의
- (void)viewWillAppear:(BOOL)animated 
{
[self.sectionData removeAllObjects];
NSMutableArray *temp[[self.index count]];
for(int i = 0; i < [self.index count]; i++)
{
temp[i] = [NSMutableArray arrayWithCapacity:100];
}
NSArray *name = [subData objectForKey:@"data"];
for(int i = 0; i < [self.index count]; i++)
{
NSString *pre = [self.index objectAtIndex:i];
for(int j = 0; j < [name count]; j++)
{
NSString *str = [name objectAtIndex:j];
if([pre isEqualToString:[self subtract:str]])
{
[temp[i] addObject:str];
}
}
}
for(int i = 0; i < [self.index count]; i++)
{
if([temp[i] count] != 0){
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:[self.index objectAtIndex:i], @"section_name", temp[i], @"data", nil];
[self.sectionData addObject:data];
}
}
[self.tableView reloadData];
    self.title = [self.subData objectForKey:@"Team"];
[super viewWillAppear:animated];
}

10. SubViewController. m  파일에  섹션을 만드는 메서드 재정의
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
return [self.sectionData count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSDictionary *Dic = [self.sectionData objectAtIndex:section];
NSString *sectionName = [Dic objectForKey:@"section_name"];
return sectionName;
}

11. SubViewController. m  파일에  셀을 만드는 메서드 재정의
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    NSDictionary *Dic = [self.sectionData objectAtIndex:section];
NSMutableArray *ar = [Dic objectForKey:@"data"];
return [ar count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSDictionary *Dic = [self.sectionData objectAtIndex:indexPath.section];
NSMutableArray *ar = [Dic objectForKey:@"data"];
cell.textLabel.text = [ar objectAtIndex:indexPath.row];
   
    return cell;
}

12. SubViewController. m  파일에  인덱스를 만드는 메서드 재정의
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.index;
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
for(int i = 0; i < [self.sectionData count]; i++)
{
NSDictionary *Dic = [self.sectionData objectAtIndex:i];
NSString *sectionName = [Dic objectForKey:@"section_name"];
if([sectionName isEqualToString:title])
{
return i;
}
}
return -1;
}






Posted by windship