iOS 動態調整tableViewCell 高度


效果圖:

 

分析:從plist文件中讀取數據源,plist最外層是一個Array,Array中存放的是字典,每個字典存放的key值並不完全相同。

    

一、單元格復用問題

1、首先讀取數據源,建立數據模型,這里我只創建了一個數據模型,包含plist中所有的key值所對應的屬性。

2、創建tableView,同時定制Cell,

  根據category,可以分成四種單元格,在tableView創建單元格時創建4種代碼如下:

 1 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 2 {
 3 
 4     CustomCell * appcustomCell = [tableView dequeueReusableCellWithIdentifier:@"appcustomCell"];
 5    
 6     if (!appcustomCell) {
 7         appcustomCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"appcustomCell"];
 8         NSLog(@"appcustomCell");
 9     }
10     
11     CustomCell * listcustomCell = [tableView dequeueReusableCellWithIdentifier:@"listcustomCell"];
12     
13     if (!listcustomCell) {
14         listcustomCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"listcustomCell"];
15         NSLog(@"listcustomCell");
16     }
17     
18     CustomCell * origincustomCell = [tableView dequeueReusableCellWithIdentifier:@"origincustomCell"];
19     
20     if (!origincustomCell) {
21         origincustomCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"news"];
22         NSLog(@"origincustomCell");
23     }
24     
25     CustomCell * largecustomCell = [tableView dequeueReusableCellWithIdentifier:@"largecustomCell"];
26     
27     if (!largecustomCell) {
28         largecustomCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"largecustomCell"];
29         NSLog(@"largecustomCell");
30     }
31     
32     
33     
34     Model *model = [_dataSource objectAtIndex:indexPath.row];
35     
36     
37     if ([model.category isEqualToString:@"list"]) {
38         listcustomCell.category = model.category;
39         listcustomCell.message = model.title ;
40 
41         listcustomCell.imageNames =  model.pics;
42         listcustomCell.source = model.source;
43         listcustomCell.time = model.time ;
44         return listcustomCell;
45         
46         
47     }
48     if ([model.category isEqualToString:@"origin"]) {
49         origincustomCell.category = model.category;
50         origincustomCell.message = model.title ;
51 
52        origincustomCell.picture = model.picture ;
53        origincustomCell.source =  model.source;
54         return origincustomCell;
55     }
56     
57     if ([model.category isEqualToString:@"large"]) {
58        largecustomCell.category = model.category;
59         largecustomCell.message = model.title ;
60 
61        largecustomCell.picture =  model.picture;
62         largecustomCell.source = model.source;
63         largecustomCell.time = model.time;
64         return largecustomCell;
65     }
66     
67     if ([model.category isEqualToString:@"app"]) {
68         appcustomCell.category = model.category;
69         appcustomCell.message = model.title ;
70 
71        appcustomCell.icon = model.icon;
72        appcustomCell.appname = model.appname;
73         return appcustomCell;
74     }
75     return nil;
76 }

 

上面是防止復用時出錯的辦法

二、題目的重點:Cell動態調整高度

1、動態調整單元格的高度,那么肯定要調用tableView代理的一個方法,換回單元格高度,代碼如下: 1 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

 2 {  3     //用來返回每一行的高度  4     //只有確定了數據,能才知道行的高度,所以在這先要去取得數據
 5     Model * model = [_dataSource objectAtIndex:indexPath.row];  6     //因為計算行高這個事是cell來計算的,所以還得需要創建一個cell對象  7     //為了去避免在計算行高時,開辟多個cell對象空間,造成資源的浪費  8     //所以在這里,要實現cell的復用
 9      cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"xx"]; 10     if (!cell) { 11         cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"xx"]; 12         
13  } 14     
15     //將數據賦給cell,然后cell去計算行高
16     //這里說的計算是,數據賦值給Cell的時候,都要調用定制Cell類中的對應屬性的set方法,在set方法中返回rowHight,rowHight也是Cell的屬性
17 //這樣按照單元格中的各個控件的順序返回相應的高度,一定要注意控件的排放順序 18 cell.category = model.category; 19 cell.message = model.title ; 20 if ([model.category isEqualToString:@"list"]) { 21 cell.imageNames = model.pics; 22 cell.source = model.source; 23 cell.time = model.time ; 24 25 26 } 27 if ([model.category isEqualToString:@"origin"]) { 28 cell.picture = model.picture ; 29 cell.source = model.source; 30 } 31 32 if ([model.category isEqualToString:@"large"]) { 33 cell.picture = model.picture; 34 cell.source = model.source; 35 cell.time = model.time; 36 } 37 38 if ([model.category isEqualToString:@"app"]) { 39 cell.icon = model.icon; 40 cell.appname = model.appname; 41 42 } 43 44 45 46 47 //因為cell里賦值后可以利用賦值內容來計算出行高,所以在賦值后,直接返回行高 48 return cell.rowHeight; 49 50 51 }

2、在定制單元格中返回該控件的高度,通過重寫控件的set方法確定該控件是否顯示,代碼:

 

 1 -(void)setSource:(NSString *)source
 2 {
 3 
 4     _source = source;
 5     if (![_category isEqualToString:@"app"]) {
 6         sourceLabel.hidden = NO;
 7         sourceLabel.text = _source;
 8         sourceLabel.frame = CGRectMake(10, _rowHeight, 100, 15);
 9     }

   //消息所有的工作做完后,要重新雲計算一下行高

 
         

    //下面這個方法是用來取一個控件的最大y值

 
         

    //這個值是從原點y坐標 + 控件高度

 
         

    //實際行高等於 上個值 再加 5

10  _rowHeight = CGRectGetMaxY(sourceLabel.frame) + 5;
11     
12 }

在Cell定制類中首先加一個Label控件,設置為隱藏,因為不知道這個控件是不是真的需要,所以當調用控件對應內容的set方法時時肯定要使用這個控件了,將控件隱藏屬性設置為NO,這里需要重新為控件布局。因為在這個控件之前不知道已有的控件占了多少高度,這里通過rowHight屬性獲得前面的高度,然后返回時加上自己的高度,加上5是為了調整控件之間的距離吧.

3、不得不說的是label中內容很多時怎么計算其高度,

 

 1 -(void)setMessage:(NSString *)message
 2 {
 3    
 4     //判斷一下有沒有消息
 5     if (message.length == 0) {
 6         //如果沒有消息
 7         messageLabel.hidden = YES;
 8         _rowHeight = 60.0f;
 9         return;
10     }
11     //如果有消息
12     //將參數消息賦給屬性
13     _message = message;
14     //有消息要顯示,那么就將控件顯示出來
15     messageLabel.hidden = NO;
16     //求出這條消息實際占用的高度
17     //下面這個方法用來求出消息內容實際占的size
18     //    message sizeWithFont:(UIFont *)
19     CGSize size = [message boundingRectWithSize:CGSizeMake(255, 9999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size;
20     //根據計算過后的消息所占的寬高,來調整messageLabel的frame
21     if ([_category isEqualToString:@"origin"]) {
22         messageLabel.frame = CGRectMake(5, 20, 180, size.height);
23     }
24     else
25     {
26         messageLabel.frame = CGRectMake(5, 5, 310, size.height);
27     }
28     
29     //給消息控件賦值
30     messageLabel.text = message;
31     
32     //消息所有的工作做完后,要重新雲計算一下行高
33     //下面這個方法是用來取一個控件的最大y值
34     //這個值是從原點y坐標 + 控件高度
35     //實際行高等於 上個值 再加 5
36     _rowHeight = CGRectGetMaxY(messageLabel.frame) + 5;
37     
38 
39 }

最重要的應該是這個方法了:

CGSize size = [message boundingRectWithSize:CGSizeMake(255, 9999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size;不太清除是什么意思,只知道根據message字體大小計算出了一個CGSize,



總結:前面說了要做出的效果,然后說了不同單單元格解決復用重疊的方法,最后說了自動調整高度。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM