前言
還在手動計算UITableViewCell
的行高嗎?還在每次都因爲需求變化一點就要大量調整cell
的高度而煩惱嗎?現在教大家如何通過Masonry
的自動佈局來實現自動計算cell
的行高!!!
在github
沒有找到基於Masonry
自動計算行高的庫,倒是找到了使用xib/storyboard
在添加約束來自動計算行高的庫,如: UITableView-FDTemplateLayoutCell
本人非常推崇Masonry
來實現代碼的自動佈局,因此項目中都是使用Masonry
佈局的,爲了自動計算行高,決定寫一個擴展,以達到自動計算的效果,如此一來,開發者不用再關心那些非固定行高的cell
的動態計算問題了。
設置關鍵依賴
要想自動計算出cell
的行高,我們還需要指定以哪個視圖作爲cell
的最後一個視圖,比如我們最後要添加一條線,我們可以以這條線作爲hyb_lastViewInCell
,如果這條線還需要距離底部一定距離,那麼可以設置hyb_bottomOffsetToCell
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/**
*
必傳設置的屬性,也就是在cell中的contentView內最後一個視圖,用於計算行高
*
例如,創建了一個按鈕button作爲在cell中放到最後一個位置,則設置爲:self.hyb_lastVieInCell = button;
*
即可。
*
默認爲nil,如果在計算時,值爲nil,會crash
*/
@property
(nonatomic,
strong)
UIView
*hyb_lastViewInCell;
/**
*
可選設置的屬性,默認爲0,表示指定的hyb_lastViewInCell到cell的bottom的距離
*
默認爲0.0
*/
@property
(nonatomic,
assign)
CGFloat
hyb_bottomOffsetToCell;
|
計算行高API
要計算行高,只需要在UITableView
的計算行高的代理方法中調用此API即可:
1
2
3
4
5
6
7
8
9
10
11
|
/**
*
通過此方法來計算行高,需要在config中調用配置數據的API
*
*
@param indexPath 必傳,對應的indexPath
*
@param confi 必須要實現,且需要調用配置數據的API
*
*
@return 計算的行高
*/
+
(CGFloat)hyb_heightForIndexPath:(NSIndexPath
*)indexPath
config:(HYBCellBlock)config;
|
在調用時,config
傳回來了cell
對象,需要在調用處調用方法來配置好數據,才能正確地計算出cell
的行高。通常是這樣調用的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-
(CGFloat)tableView:(nonnull
UITableView
*)tableView
heightForRowAtIndexPath:(nonnull
NSIndexPath
*)indexPath
{
HYBNewsModel
*model
=
nil;
if
(indexPath.row
<
self.dataSource.count)
{
model
=
[self.dataSource
objectAtIndex:indexPath.row];
}
return
[HYBNewsCell
hyb_heightForIndexPath:indexPath
config:^(UITableViewCell
*sourceCell)
{
HYBNewsCell
*cell
=
(HYBNewsCell
*)sourceCell;
//
配置數據
[cell
configCellWithModel:model];
}];
}
|
實現例子
效果圖如下:
我們看下實現-initWithStyle: reuseIdentifier:
方法,因爲我們要自動計算cell
行高會自動調用此方法,因此一定要實現此方法來佈局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
-
(nonnull
instancetype)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(nullable
NSString
*)reuseIdentifier
{
if
(self
=
[super
initWithStyle:style
reuseIdentifier:reuseIdentifier])
{
self.mainLabel
=
[[UILabel
alloc]
init];
[self.contentView
addSubview:self.mainLabel];
self.mainLabel.numberOfLines
=
0;
[self.mainLabel
sizeToFit];
[self.mainLabel
mas_makeConstraints:^(MASConstraintMaker
*make)
{
make.left.mas_equalTo(15);
make.top.mas_equalTo(20);
make.right.mas_equalTo(-15);
make.height.mas_lessThanOrEqualTo(80);
}];
//
如果需要支持6.0,需要加上這句
// self.mainLabel.preferredMaxLayoutWidth
= ...
self.descLabel
=
[[UILabel
alloc]
init];
[self.contentView
addSubview:self.descLabel];
self.descLabel.numberOfLines
=
0;
[self.descLabel
sizeToFit];
[self.descLabel
mas_makeConstraints:^(MASConstraintMaker
*make)
{
make.left.mas_equalTo(15);
make.right.mas_equalTo(-15);
make.top.mas_equalTo(self.mainLabel.mas_bottom).offset(15);
}];
//
如果需要支持6.0,需要加上這句
// self.mainLabel.preferredMaxLayoutWidth
= ...
self.button
=
[UIButton
buttonWithType:UIButtonTypeSystem];
[self.contentView
addSubview:self.button];
[self.button
sizeToFit];
[self.button
setTitle:@"我是cell的最後一個"
forState:UIControlStateNormal];
[self.button
setBackgroundColor:[UIColor
greenColor]];
[self.button
mas_makeConstraints:^(MASConstraintMaker
*make)
{
make.left.mas_equalTo(15);
make.right.mas_equalTo(-15);
make.height.mas_equalTo(45);
make.top.mas_equalTo(self.descLabel.mas_bottom).offset(40);
}];
//
必須加上這句
self.hyb_lastViewInCell
=
self.button;
self.hyb_bottomOffsetToCell
=
20;
}
return
self;
}
|
注意到這兩行代碼了嗎:
1
2
3
4
|
self.hyb_lastViewInCell
=
self.button;
self.hyb_bottomOffsetToCell
=
20;
|
先是設置哪個視圖作爲cell
的最後一個視圖,然後設置了最後一個參考視圖與cell
的底部的距離。其中,self.hyb_lastViewInCell
屬性是必須要設置的,否則會拋出異常。
使用
這個組件是開源的,而且是支持cocoapods
的,因此大家若是使用了cocoapods
來管理項目第三方庫,可以這樣使用:
1
2
3
|
pod
'HYBMasonryAutoCellHeight',
'~>
0.0.1'
|
如果項目未使用cocoapods
,直接下載源代碼,然後將HYBMasonryAutoCellHeight
文件夾拖入工程即可使用!
源代碼
大家可以到github
下載源代碼來看看,內部實現很簡單,當然要實現自動計算行高也是有系統方法的,不一定需要像筆者這樣來實現。
下載源代碼:https://github.com/CoderJackyHuang/HYBMasonryAutoCellHeight
喜歡就給個star
關注我
如果在使用過程中遇到問題,或者想要與我交流,可加入有問必答QQ羣:324400294
關注微信公衆號:iOSDevShares
關注新浪微博賬號:標哥Jacky