iPhone App2011. 8. 19. 17:19

으아~~

쓴거 다 날라갔다 힘들게 썻는데

참고한곳 : http://blog.keyoptions.co/tableview-with-automatic-load-more

참조한곳 소스: 


내가 수정한 소스 



Posted by 동동(이재동)
iPhone App2011. 8. 16. 17:57

TableView를 이용해서 SNS를 개발 하기위해 선두지점에 있는 Facebook 앱을 보았다.


201108161711.jpg

이렇게 Label이 길수록 TableView cell row가 길게 나왔다.

이렇게 할려면 글을 길이를 계산해서 row의 높이를 계산해야 한다.

#define FONT_SIZE 14.0f

#define CELL_CONTENT_WIDTH 320.0f

#define CELL_CONTENT_MARGIN 10.0f


일단 사이즈를 계산하기 위해 고정적인 정보를 정의 했다.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

{

NSString *text = [items objectAtIndex:[indexPath row]];

  

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

  

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

  

CGFloat height = MAX(size.height, 44.0f);

  

return height + (CELL_CONTENT_MARGIN * 2);

}


그리고 heightForRowIndexPath 델리게이트를 이용해서 글의 길이에 따라 cell의 높이를 변화시켰다.items 에는 tableview itemsource가 담겨 있다.
자 이제 실제 label을 조정해 보자.

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

{

UITableViewCell *cell;

UILabel *label = nil;

  

cell = [tv dequeueReusableCellWithIdentifier:@"Cell"];

if (cell == nil)

{

cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"] autorelease];

  

label = [[UILabel alloc] initWithFrame:CGRectZero];

  

[label setLineBreakMode:UILineBreakModeWordWrap];

[label setMinimumFontSize:FONT_SIZE];

[label setNumberOfLines:0];

[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];

[label setTag:1];

  

// [[label layer] setBorderWidth:2.0f];

  

[[cell contentView] addSubview:label];

  

}

NSString *text = [items objectAtIndex:[indexPath row]];

  

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

  

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

  

if (!label)

label = (UILabel*)[cell viewWithTag:1];

  

[label setText:text];

[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];

  

return cell;


}


빈 label을 만들어서 add하는 형식이다. 그리고 label의 크기를 이렇게 유동적으로 변형시킨다.

[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];


이렇게 하면


201108161748.jpg


이렇게 다이나믹하게 row의 높이가 변한다.


참고 : http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/


하지만 나는 코드상에서 label을 만들어서 하지 않고 ib에서 만들어서 적용할려고 했다. 그래야 쉽지 ㅋㅋ


내가 응용한 코드는 다음과 같다.


//table height label 크기에 따라 변환

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

{

HugeBoardData* hd = [boardData objectAtIndex:indexPath.row];


CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

  

CGSize size = [hd.title sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

  

CGFloat height = MAX(size.height, 44.0f);

  

return height + (CELL_CONTENT_MARGIN * 2);

}


size에 보면 hd.title이 있다. title의 크기를 기준으로 높이를 계산해서 반환한다.


그리고 크기를 내크기에 맞게 변환했다.


#define FONT_SIZE 14.0f

#define CELL_CONTENT_WIDTH 140.0f

#define CELL_CONTENT_MARGIN 10.0f



마지막으로 cellForRowAtIndexPath 델리게이트는

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

  

HugeBoardCell *cell = (HugeBoardCell *)[tableView dequeueReusableCellWithIdentifier:HugeBoardCellIdentifier];

  

if (cell == nil) {   

cell = [HugeBoardCell cellWithNib];

[cell.titleLabel setMinimumFontSize:FONT_SIZE];

[cell.titleLabel setLineBreakMode:UILineBreakModeWordWrap];

[cell.titleLabel setNumberOfLines:0];

[cell.titleLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];

[cell.titleLabel setTag:1];

}

  

HugeBoardData* hd = [boardData objectAtIndex:indexPath.row];

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

  

CGSize size = [hd.title sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

  


cell.titleLabel.text = [NSString stringWithFormat:@"%@", hd.title];

[cell.titleLabel setFrame:CGRectMake(CELL_CONTENT_MARGIN+40, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];

cell.idxLabel.text= [NSString stringWithFormat:@"%@ : ", hd.idx];

return cell;

}


이렇게 구현했다. 달라진게 있다면 현재 titleLabel은 custom cell의 ib에서 연결된 label이다.즉 behind code에서 처리하지 않고 ib에서 이미 만든값의 크기를 다이나믹하게 변경하였다.
결과는
201108161755.jpg
맨하단에 보면 저렇게 긴글도 제대로 표시해주고 있다.

201108161756.jpg
현재 table의 cell은 이렇게 되어있다. 즉 저기 content라고 써있는 label의 높이를 변형시켰다.
이렇게 약간 페이스북에 가까이 가는거 같다.
Posted by 동동(이재동)
iPhone App2011. 7. 22. 15:28

이것참... 역시 책으로 공부하면 안되는것이다.

책에서 tableview에 내용을 넣을때 array에 넣고 안에 딕션널리 컬렉션류를 넣어서 항상 forkey를 이용하게 했었다.

그래서 이번에 xml을 파싱하여 tableview로 보여줬어야 했는데 NSObject 클래스로 만들어서 안에 있는 내용을 보여줄려고 해서

key를 쓸려니까 잘안되었다.

말로는 설명이 힘드니 직접 코드를 보자..

@interface HugeBoardData : NSObject {

NSString* _idx;

NSString* _name;

NSString* _title;

NSString* _description;

NSString* _date;

}


@property(nonatomic,retain) NSString* idx;

@property(nonatomic,retain) NSString* name;

@property(nonatomic,retain) NSString* title;

@property(nonatomic,retain) NSString* description;

@property(nonatomic,retain) NSString* date;

이런 데이터 구조를 가진 object class가 있다 여기에 데이터를 집어넣고

HugeBoardData *data = (HugeBoardData*)parentElement;

if([element isEqualToString:@"idx"])

{

data.idx = trimmedValue;

}

else if([element isEqualToString:@"Name"])

{

data.name = trimmedValue;

}

else if([element isEqualToString:@"Title"])

{

data.title = trimmedValue;

}

else if([element isEqualToString:@"Description"])

{

data.description = trimmedValue;

}

else if([element isEqualToString:@"Date"])

{

data.date = trimmedValue;

}

이런식으로 집어넣고 tableiew delegate에서

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

  

static NSString *CellIdentifier = @"Cell";

  

//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];

  

if (cell == nil) {

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

}


HugeBoardData* hd = [data objectAtIndex:indexPath.row];

  

cell.textLabel.text = [NSString stringWithFormat:@"%@. %@", hd.idx, hd.title];

cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", hd.name];


return cell;

}


이렇게

HugeBoardData* hd = [data objectAtIndex:indexPath.row];

하고 하나씩 꺼내 쓰면 된다 그러면 원하는 idx,title,name등을 골라서 뽑아 쓰면 된다.

막상 인터넷에도 없고 책에는 다 딕셔널리로 되어 있어서 상당히 헷갈렸던 부분이다.

앞으로 array안에 꼭 데이터를 저렇게 넣고 빼서 써야겠다 어찌보면 간단한건데 헷갈렸던것이다.


Posted by 동동(이재동)