2010年8月4日 星期三

動態調整TableVewCell的高度

因為工作需求,原本要使用UITextView來顯示多行文字,但是發現使用了UITextView之後,Cell可以觸發select動作的區域將變得很小(受到UITextView的區域影響)。所以改用別的方式處理。

首先,發現原來UILabel是可以顯示多行文字的,只要把property numberOfLines設為0,就可以支援多行文字,但是必須呼叫[label sizeToFit],來調整UILabel的大小。

而預設的UITableViewCell的textLabel也可以這樣調整,所以就可以顯示多行文字。然而,UITableView還有個問題,就是有cell height的問題。因為cell height似乎是在cell顯示前就會設定好,所以即使在tableView:cellForRowAtIndexPath:這個method裡面去調整cell的高度也是無效。必須透過tableView:heightForRowAtIndexPath:來回傳特定cell的高度。

但是,對於多行文字來說,因為內容行數是不固定的,所以必須在顯示時計算實際行數文字的總高度。幸好在參考iPhone SDK: Resizing a UITableViewCell to Hold Variable Amounts of Text, Part 2 of 2這篇之後,得到解答。就是利用NSString裡面的sizeWithFont:constrainedToSize:lineBreakMode:來根據指定的字型高度跟斷行方式來計算。可以使用Objective-C的Category機制,將此method放置到NSString中。以下是參考上述文章所寫的code:
@implementation NSString (TextHeight)
-(CGFloat) textHeightForSystemFontOfSize:(CGFloat)size {
//Calculate the expected size based on the font and linebreak mode of the label
CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 50;
CGFloat maxHeight = 9999;
CGSize maximumLabelSize = CGSizeMake(maxWidth,maxHeight);
CGSize expectedLabelSize = [self sizeWithFont:[UIFont systemFontOfSize:size] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap];
return expectedLabelSize.height;
}
@end

透過此method,就可以在tableView:heightForRowAtIndexPath:中回傳正確的文字內容高度了。

沒有留言: