iOS7和iOS8下的自適應(yīng)cell

轉(zhuǎn)載文章占键,純粹為知識(shí)分享

我們開(kāi)發(fā)中,在使用UITableView的時(shí)候經(jīng)常會(huì)遇到這樣的需求:table view的cell中的內(nèi)容是動(dòng)態(tài)的君仆。于是我們就在table view的代理中手動(dòng)去計(jì)算cell中的內(nèi)容高度牲距。這樣做有兩個(gè)問(wèn)題:

計(jì)算代碼冗長(zhǎng)、復(fù)雜咖摹。

每次 reload tableview 的時(shí)候难述,系統(tǒng)會(huì)先計(jì)算出每一個(gè) cell 的高度吐句,等所有高度計(jì)算完畢店读,確定了 tableview 的contentSize后,才開(kāi)始渲染視圖并顯示在屏幕上文虏。如果數(shù)據(jù)比較多殖演,就會(huì)感受到非常明顯的卡頓。

所以趴久,我們應(yīng)該尋找其他的解決方案。如果你的項(xiàng)目只支持iOS8及以上,那么恭喜你滥酥,你只用簡(jiǎn)單的幾步就可以實(shí)現(xiàn)自適應(yīng)cell了畦幢。如果是iOS7也沒(méi)關(guān)系,后面我也會(huì)講到宇葱,如何在iOS下實(shí)現(xiàn)自適應(yīng)cell。

在講具體的實(shí)現(xiàn)之前诸尽,必須得說(shuō)一下iOS7中新增的一個(gè)API:

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;

這個(gè)方法用于返回一個(gè) cell 的預(yù)估高度印颤,如果實(shí)現(xiàn)了這個(gè)代理方法,tableview 首次加載的時(shí)候就不會(huì)調(diào)用heightForRowAtIndexPath 方法际看,而是用 estimatedHeightForRowAtIndexPath 返回的預(yù)估高度計(jì)算 tableview 的contentSize矢否,然后 tableview 就可以顯示出來(lái)了,等到 cell 可見(jiàn)的時(shí)候赖欣,再去調(diào)用heightForRowAtIndexPath 獲取 cell 的正確高度。

通過(guò)實(shí)現(xiàn)這個(gè)代理方法畏鼓,解決了首次加載 table view 出現(xiàn)的性能問(wèn)題,但是并沒(méi)有讓我們從復(fù)雜的計(jì)算中解脫出來(lái)膳沽。下面我會(huì)通過(guò)例子來(lái)講解一下在iOS7和iOS8中自適應(yīng)cell的實(shí)現(xiàn)让禀。

iOS8的自適應(yīng)cell

要想讓table view的cell自適應(yīng),有幾個(gè)要點(diǎn):

設(shè)置的AutoLayout約束必須讓 cell 的contentView知道如何自動(dòng)伸展痛阻。關(guān)鍵點(diǎn)是contentView的 4 個(gè)邊都要設(shè)置連接到內(nèi)容的約束腮敌,并且內(nèi)容是會(huì)動(dòng)態(tài)改變尺寸的。其實(shí)只要記住弊添,我們?cè)谠O(shè)置約束時(shí)只要能讓contentView能被內(nèi)容撐起來(lái)就可以了捌木。

UITableView 的rowHeight的值要設(shè)置為UITableViewAutomaticDimension。

和 iOS 7 一樣刨裆,可以實(shí)現(xiàn) estimatedHeightForRowAtIndexPath 代理方法提升 table view 的第一次加載速度。也可以直接這樣:self.tableView.estimatedRowHeight =? 60瞬女。

好了咱們來(lái)直接上代碼:

在 Xcode 中新建一個(gè)項(xiàng)目努潘,設(shè)置好tableView后,自定義一個(gè)UITableViewCell:

屏幕快照 2016-02-24 上午10.25.12.png

創(chuàng)建好之后是這樣的:

屏幕快照 2016-02-24 上午10.35.26.png

下面來(lái)看一下約束,這個(gè)是決定你的cell能否自適應(yīng)的關(guān)鍵贴膘。

UIImageView約束如下:

左邊距離contentView左邊15

頂部距離contentView頂部8

width和height為 40

底部距離contentView底部大于或等于0(為了防止文本內(nèi)容太少,導(dǎo)致 cell 高度小于圖片高度)

UILabel有四個(gè)約束:

左邊距離圖片8

右邊距離contentView右邊15

頂部距離contentView頂部8

底部距離contentView底部4

不要忘了將UILabel的numberOfLines設(shè)為0

以上約束就可以將contentView撐起來(lái)了洋闽。

控制器中代碼如下:

- (void)viewDidLoad {? ? [superviewDidLoad];// Do any additional setup after loading the view, typically from a nib.self.tableView.estimatedRowHeight =60;self.tableView.rowHeight =UITableViewAutomaticDimension;? ? [self.tableView registerNib:[Cell1 nib] forCellReuseIdentifier:[Cell1 identifier]];}

- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {? ? Cell1 *cell1 = [tableViewdequeueReusableCellWithIdentifier:[Cell1 identifier]forIndexPath:indexPath];? ? cell1.textLab.text = self.data[indexPath.row];returncell1;}

決定cell自適應(yīng)內(nèi)容的也就這兩行代碼:self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 60;

看一下效果:

屏幕快照 2016-02-24 上午10.49.42.png

iOS7的自適應(yīng)cell

iOS7相比iOS8實(shí)現(xiàn)起來(lái)代碼多一點(diǎn)但是并不復(fù)雜诫舅,還是用上個(gè)例子中的cell,

我們?cè)趆eightForRowAtIndexPath中計(jì)算高度:

- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {NSString*identifier = [Cell1 identifier];? ? Cell1 *cell1 =self.offScreenCells[identifier];if(!cell1) {? ? ? ? cell1 = [[[NSBundlemainBundle] loadNibNamed:@"Cell1"owner:niloptions:nil] lastObject];self.offScreenCells[identifier] = cell1;? ? }? ? cell1.textLab.text =self.data[indexPath.row];? ? [cell1 setNeedsUpdateConstraints];? ? [cell1 updateConstraintsIfNeeded];CGFloatheight = [cell1.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;returnheight +1;}

這里主要使用systemLayoutSizeFittingSize:來(lái)獲取內(nèi)容的高度,所以在獲取高度之前我們必須有一個(gè)實(shí)例化的cell这弧。我在這里使用字典存儲(chǔ)cell虚汛,主要是因?yàn)橐粋€(gè)tableView中可能有多種不同的cell。獲取到cell之后將內(nèi)容添加上去蛋辈,然后更新約束将谊。

屏幕快照 2016-02-24 上午11.27.10.png

要想實(shí)現(xiàn)上圖效果還有一個(gè)需要注意的地方,那就是要給顯示label的preferredMaxLayoutWidth賦一個(gè)值:

- (void)awakeFromNib {// Initialization codeself.textLab.preferredMaxLayoutWidth =250;}

也可以在給label設(shè)置約束時(shí)直接將width定死逞频,而不是通過(guò)距離contentView右邊間距來(lái)確定寬度眠砾。

以上就是在iOS7及以上版本中實(shí)現(xiàn)自適應(yīng)cell的方法托酸,如果有什么錯(cuò)誤,希望大家能指正励堡。你們的支持將是我寫作的最大動(dòng)力应结。

貼一下demo地址:iOS7和iOS8下的自適應(yīng)cell

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市揩慕,隨后出現(xiàn)的幾起案子扮休,更是在濱河造成了極大的恐慌,老刑警劉巖玷坠,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異樟凄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)汰现,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門二拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人企软,你說(shuō)我怎么就攤上這事饭望。” “怎么了铅辞?”我有些...
    開(kāi)封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵斟珊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我囤踩,道長(zhǎng),這世上最難降的妖魔是什么综慎? 我笑而不...
    開(kāi)封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任勤庐,我火速辦了婚禮,結(jié)果婚禮上米罚,老公的妹妹穿的比我還像新娘丈探。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布辨宠。 她就那樣靜靜地躺著货裹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赋兵。 梳的紋絲不亂的頭發(fā)上搔预,一...
    開(kāi)封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音历造,去河邊找鬼船庇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸭轮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邑蒋,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼按厘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼刻剥!你這毒婦竟也來(lái)了滩字?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤麦箍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后享钞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡暑脆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年狐肢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碟联。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡僵腺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出普监,到底是詐尸還是另有隱情琉兜,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布漆际,位于F島的核電站夺饲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏往声。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一贯涎、第九天 我趴在偏房一處隱蔽的房頂上張望慢洋。 院中可真熱鬧,春花似錦普筹、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)幔嗦。三九已至沥潭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叛氨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工屁置, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仁连,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓使鹅,卻偏偏與公主長(zhǎng)得像昌抠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炊苫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容