iPhone App2011.08.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 동동(이재동)