因?yàn)楣卷?xiàng)目的計(jì)算高度library,經(jīng)常在ios7的幾個(gè)little version上發(fā)生crash,特發(fā)此文。
要求Version >= IOS7.0
高度計(jì)算的歷程
<pre>
- calucate manully,通過
[self.userComment.text boundingRectWithSize:<#(CGSize)#> options:<#(NSStringDrawingOptions)#> attributes:<#(nullable NSDictionary<NSString *,id> *)#> context:<#(nullable NSStringDrawingContext *)#>]<bre>
[self.userComment sizeThatFits:<#(CGSize)#>];
這樣的方法來計(jì)算高度,最后把各種 margin 、labelHeight、textviewHeigt加在一起,逐步計(jì)算。
- 在AutoLayout大家都認(rèn)可之后,開始使用systemLayoutSizeFittingSize來計(jì)算高度
- 然后就是iOS8的 self-sizing cell ,使用 frame layout 和 auto layout 都可以。
self.tableView.estimatedRowHeight = 213;
self.tableView.rowHeight = UITableViewAutomaticDimension;
</pre>
好了下面進(jìn)入正題。
首先計(jì)算高度,如果是固定高度,強(qiáng)烈推薦使用self.tableView.rowHeight這個(gè)屬性來設(shè)置高度,這樣就避免了,計(jì)算。讓界面更加的流暢,你懂得。
如果你重寫了代理方法。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
剛開始設(shè)置的屬性會(huì)被覆蓋。
下一個(gè)設(shè)置cell height的方法是self.tableView.estimatedRowHeight和代理方法-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
這兩個(gè)東西,也提高了tableview的性能,當(dāng)數(shù)據(jù)很多時(shí),讓它不是那么卡頓。
為什么?以前都是根據(jù)數(shù)據(jù)源的個(gè)數(shù),剛開始就計(jì)算所有的高度。有了它之后呢,只有當(dāng)滑動(dòng)到這里的時(shí)候才計(jì)算。
next is -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
在這里我們計(jì)算的時(shí)候我們需要一個(gè)專門來計(jì)算高度的cell,為什么呢,因?yàn)橛?jì)算方法是view的一個(gè)實(shí)例方法在此方法里面。而且在-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath方法里,cell的重用失效了···,這個(gè)很奇怪哈。
我們可以定義一個(gè)static 的cell來,使用它的實(shí)例方法[cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]計(jì)算size,
在此之前調(diào)用一下更新約束的方法[cell layoutIfNeeded];讓計(jì)算更可靠點(diǎn)。
不過這里有個(gè)注意點(diǎn),在有多行l(wèi)abel的時(shí)候,需要指定它的寬度像這樣self.userComment.preferredMaxLayoutWidth = 293;否則它是不會(huì)換行的。
這樣計(jì)算下來高度還是不對(duì),為什么呢?
高度還差1,因?yàn)槟阌?jì)算的時(shí)contentview的高度,cell的實(shí)際高度比contentview的高度還高1哦。
這種方法和以前相比已經(jīng)方便很多了,但是,計(jì)算的速度沒有手算的快,所以如果考慮不到位,卡頓現(xiàn)象就會(huì)很明顯。
上面的方法需要同學(xué)對(duì)約束掌握熟練,保證上下左右都有約束支撐。特別是在視圖很多的時(shí)候,約束很可能出現(xiàn)沖突,大家要靈活的運(yùn)用priority、content hugging、content compression,這些屬性解決沖突
有不足的地方請同學(xué)補(bǔ)充,謝謝。需要demo的同學(xué)留下地址
Tip
因?yàn)閁ILabel和UITextView,都存在多行展示的問題,所以要下知道最大寬度,這里我們可以這樣
- (void)layoutSubviews
{
[super layoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[super layoutSubviews];
}
第一次調(diào)用[super layoutSubviews]是為了獲得label現(xiàn)在的真實(shí)frame,第二次調(diào)用是為了更新布局。