你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> 有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

編輯:關於IOS

本文是投稿文章,作者:iOS122


Apple 算是最重視應用開發體驗的公司了。從Xib到StoryBoard,從Auto Layout到Size Class,每一次的更新,都會給iOS應用的開發帶來不小的便利。但是,對於絕對多數iOS攻城獅來說,我們依然還是很害怕寫UITabelVIew的自適應布局。當然,害怕不是因為我們不會寫,或者本身有什麼特殊的技術點,而是因為太麻煩。當然,文章的後半部分,會給出相應的解決方案,畢竟本文不是為了吐槽而吐槽。

UITabelView的自適應布局有多麻煩?

數據類型的不確定性:種類越多,頁面越復雜。

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

網易新聞

以網易新聞的客戶端為例,可能的數據包括文字新聞,圖片新聞,圖集,推廣,視頻等。每一種數據,又根據來源或點擊量等細分出許多不同的狀態。基本上每種數據類型,都至少需要一種單獨的Cell去呈現,每一個Cell的布局,都要單獨去寫。所以說,數據的類型將直接決定頁面本身的復雜度。

數據長度的不確定性: 不確定字段越多,迭代成本越高。

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

新浪微博

上圖取自新浪微博。稍微有點經驗的iOS攻城獅,都猜到我要吐槽什麼了吧!沒錯,就是同種數據類型,但是內部字段的長度可能不同,而且還要都要給他們顯示出來!其實我也很希望自家的應用都像網易那樣,固定長度顯示新聞,顯示不完,就直接截斷--可惜那樣的應用都是別人公司的應用。可能你會說: 頂部給個非微博正文區域給個固定高度;文字區域動態計算出高度;圖片部分,圖片高度固定,根據數量動態計算高度;轉發部分同理;然後根據數據在tabelView的代理方法 tableView:heightForRowAtIndexPath: 中動態返回高度即可。是的,思路就是這麼個思路,但是你確定產品經理一直不會改需求?你確定不需要適配 6plus時,字號要大點?你確定自己的應用不希望大屏上一樣能顯示更多的圖片?你確定老板不是盤算著 iPad版也交給你維護?所以說,對於這種數據長度不確定,但是又要求完全顯示的設計,最復雜的不在於實現,而在於後期的迭代。可變字段越多,迭代越復雜。如果連顯示方式都改了,那就基本等於重做了幾遍。

cell高度計算有坑: 難以理解的詭異問題

在 tableView:heightForRowAtIndexPath: 中計算高度時,是有坑的,對於剛接觸iOS的攻城獅來說,幾乎是難以理解的詭異問題。這裡簡單說兩個,其他的大家可跟帖補充:

  • 文字高度計算時 0.1 高度誤差問題。

cell中經常需要使用 textRectForBounds: limitedToNumberOfLines: 來計算某一個文字的顯示高度。這裡,其實有一個很大的坑的,如果你沒遇到只能說明你很幸運。由於浮點數四捨五入機制的存在,所以偶現UILabel最後一行無法顯示的情況。原因也很詭異: 在你計算時,部分值會存在稍許的不超過0。01的誤差,大多數情況下,這個誤差值,可以安全忽略,但是確實存在那0。01誤差剛好是絕對換行與不換行的分界值,因為0。01的誤差,可能計算出來的高度就不足以顯示最後幾個文字。為了安全起見,如果需要計算文本高度,我都是加上一個額外的0。1來保證最後一行肯定可以顯示。

  • 手動調用 tableView:cellForRowAtIndexPath: 獲取cell,引起的卡頓問題。

這個可能也是一些有經驗的開發者也會混淆的問題: 不要在自己的代碼中調用 tableView:cellForRowAtIndexPath: 方法來獲取某一個位置的 cell,來進行關於這個cell的某些計算,因為你手動調用這個方法產生的cell不會參與cell的復用! 各種緣由,不過多解釋,總之結論就是,只要系統自己調用 tableView:cellForRowAtIndexPath: 方法產生的 cell才會參與cell的復用。

關於這個話題,比較易犯的錯誤是,竟然有開發者在tableView:heightForRowAtIndexPath: 中調用 tableView:cellForRowAtIndexPath: 來獲取cell,然後計算cell高度。然後你會發現,凡是稍微涉及到圖片顯示的界面,你的顯示是對的,但是滾動非常卡頓,因為你在自己渾然不覺的情況下創建了N個Cell,而且這些Cell絕對不會參與復用。

為什麼我現在不再害怕寫UITabelView的自適應布局?

是的,我現在一點也不擔心去處理各種UITabelView布局。不是因為我有一股所謂的不畏艱難的偉大工作精神,而是因為我切實找到了解決辦法。具體該怎麼做呢?

  • 使用AutoLayout 布局你的cell

坦白說,咱都是剛入行的人,使用AutoLayout布局,寫一個自適應的Cell,大家估計也都會。可以用xib,也可以用純代碼寫。如果准備用純代碼寫,建議你先好好研究下 Masonry - 使用純代碼進行iOS應用的autolayout自適應布局

  • 使用 UITableView-FDTemplateLayoutCell 根據單元格內容的約束自適應單元格高度

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

博客討論

坦白說,我原來也是: 雖然cell用著AutoLayout,但是計算cell高度時,也是看著設計圖返回一個適合的值--想想都虐心。前天,一個熱心的開發者在我博客留言說: 他用 Masonry 進行Cell的高度自適應時遇到了問題。我第一反應是: Masonry 能用來計算cell高度?! 然後,他提到了一個第三方UITableView-FDTemplateLayoutCell,好像是國內的大神寫的,具體介紹可以看這裡: 優化UITableViewCell高度計算的那些事。這篇文章的博主關於 UITableView-FDTemplateLayoutCell 分析很詳盡,用一句總結就是: 一行代碼解決cell高度動態計算問題。

  • 一個關於Masonry 和 UITableView-FDTemplateLayoutCell結合使用的小例子

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?

一個關於Masonry 和 UITableView-FDTemplateLayoutCell結合使用的小例子

示例下載地址: 點擊下載

非常感謝 @未來帥哥 的討論,給了我很大啟發和幫助,我也如約做了一個關於Masonry 和 UITableView-FDTemplateLayoutCell結合使用的小例子,以解決他的問題:關於如何讓左側圖片底部總是不被遮蓋。

核心代碼片段:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {          CGFloat height = [tableView fd_heightForCellWithIdentifier: NSStringFromClass([YFAutoLayoutCell class]) cacheByIndexPath:indexPath configuration:^(YFAutoLayoutCell * cell) {         YFAutoLayoutCellModel * model = [self.data objectAtIndex: indexPath.row];                  cell.model = model;     }];          return height; }
/**  *  初始化視圖.  */ - (void) setupView {     self.imgView = [[UIImageView alloc] init];     self.introLabel = [[UILabel alloc] init];          [self.contentView addSubview: self.imgView];     [self.contentView addSubview: self.introLabel];          self.introLabel.numberOfLines = 0;          [self.imgView makeConstraints:^(MASConstraintMaker *make) {         make.top.left.equalTo(8);         make.size.equalTo(CGSizeMake(60, 60));         make.bottom.lessThanOrEqualTo(-8); // 這裡是關鍵     }];          [self.introLabel makeConstraints:^(MASConstraintMaker *make) {         make.left.equalTo(self.imgView.right).offset(8);         make.top.equalTo(self.imgView);         make.right.equalTo(-8);         make.bottom.equalTo(-8);     }]; }

小結

有了Auto Layout,為什麼你還是害怕寫UITabelView的自適應布局?因為你還在用傳統的方式去計算cell的高度! Auto Layout + UITableView-FDTemplateLayoutCell + Masonry,耐心研究幾個小時,絕對讓你受益匪淺!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved