標籤:
一、使用xib或者storyboard自訂非等高的cell實現方式差不多,這裡簡單介紹一下通過xib檔案實現的方法
<1.1>建立一個繼承自UITableViewCell的子類,比如ChaosWeiboCell
<1.2>在模型中增加一個cellHeight屬性,用來存放對應的cell的高度
#import <UIKit/UIKit.h> // 這裡修改成UIKit架構@interface ChaosWeibo : NSObject // 模型類/** 本文 */@property(nonatomic,strong) NSString *text;/** 頭像 */@property(nonatomic,strong) NSString *icon;/** 配圖 */@property(nonatomic,strong) NSString *picture;/** 使用者名稱 */@property(nonatomic,strong) NSString *name;/** VIP */@property(nonatomic,assign,getter=isVIP) BOOL vip;// CGFloat在CG架構裡面 NSString *在Foundation架構裡面,UIKit架構套件含了這兩個架構/** cell的高度 */@property(nonatomic,assign) CGFloat cellHeight;// 提供一個將字典資料轉換成模型資料的類方法+ (instancetype)WeiboWithDict:(NSDictionary *)dict;@end
<2>建立一個xib檔案(檔案名稱建議跟cell的類名一樣),比如ChaosWeiboCell.xib
<2.1>拖拽一個UITableViewCell出來
<2.2>修改cell的class為ChaosWeiboCell
<2.3>設定cell的重用標識
<2.4>往cell中添加需要用到的子控制項
<3>在控制器中
<3.1>利用registerNib...方法註冊xib檔案
<3.2>利用重用標識找到cell(如果沒有註冊xib檔案,就需要手動去載入xib檔案)
<3.3>給cell傳遞模型資料
<3.4>在控制器中實現tableView:estimatedHeightForRowAtIndexPath:方法,返回一個估計高度,比如200
// 給cell一個估計高度// 這個方法的意義在於:沒有這個方法,程式的執行順序是1、heightForRowAtIndexPath:方法得到cell的高度(高度不準確,有幾個就獲得幾個的cell高度,消耗記憶體)2、然後cellForRowAtIndexPath:方法根據不準確的高度建立cell// 有了這個方法程式會根據這個大約的高度先去執行cellForRowAtIndexPath:方法,然後再執行heightForRowAtIndexPath:方法返回真正的cell高度- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 200;}@end
<3.5>在控制器中實現tableView:heightForRowAtIndexPath:方法,返回cell的真實高度(模型中的cellHeight屬性)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ ChaosWeibo *weibo = self.weiboArray[indexPath.row]; return weibo.cellHeight;}
<4>在ChaosWeiboCell中
<4.1>將xib中的子控制項連線到類擴充中
<4.2>需要提供一個模型屬性,重寫set方法,在這個方法中設定模型屬性到子控制項上
並且在set方法中調用[self layoutIfNeed]方法強制布局,然後計算出模型的cellHeight屬性值
- (void)setWeibo:(ChaosWeibo *)weibo{ // 重寫set方法不可少的代碼 _weibo = weibo; // 設定頭像 self.headView.image = [UIImage imageNamed:weibo.icon]; // 設定暱稱 self.nameLabel.text = weibo.name; // 設定會員標誌 if (weibo.isVIP) { self.vipView.hidden = NO; // 重新將hidden屬性設定為NO,因為cell是通過緩衝池回收過來的,萬一之前是hidden,這裡沒有這一句就不行了 self.vipView.image = [UIImage imageNamed:@"vip"]; self.nameLabel.textColor = [UIColor orangeColor]; } else{ self.vipView.hidden = YES; self.nameLabel.textColor = [UIColor whiteColor]; } // 設定本文內容 self.contentLabel.text = weibo.text; if (weibo.picture) { self.iconView.hidden = NO; // 同理 self.iconView.image = [UIImage imageNamed:weibo.picture]; } else { self.iconView.hidden = YES; } // 將綁定好資料的cell進行強制布局 [self layoutIfNeeded]; // 計算cell的高度 if (self.iconView.hidden) { // 沒有配圖的情況 weibo.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + 10; } else { // 有配圖的情況 weibo.cellHeight = CGRectGetMaxY(self.iconView.frame) + 10; }}
<4.3>也可以將建立獲得cell的代碼封裝起來(比如cellWithTableView:方法)
<5>需要注意的一點就是label的寬度問題,由於layoutIfNeed方法的原因,系統有時候算出的高度會於實際不符。因為系統算的高度是根據文字寬度算的。
解決辦法,通過調用一下方法:
// 這個方法是自訂控制項從xib檔案初始化完後調用的方法,通過這個方法解決多行label算的高度不準的情況- (void)awakeFromNib{ // 設定每一行label文字的最大寬度 // 保證算出來的label的高度 跟 顯示出來的效果一樣 self.contentLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;}
iOS邊練邊學--自訂非等高的cell