Table View Cell 自適應速成大法
縱觀近幾年,有太多培訓機構當攪屎棍進來瞎摻和貴國的全民創業,偽造簡歷不說,那幫菜鳥的技術真的是辣眼睛,臥槽,好像跑偏了,今天不是來申討培訓黨的,我們是正經教程,還是回到主路繼續開車~~~
此教程特地針對Xcode8,iOS10和Swift 3優化并完善,那么你需要使用Xode8或者更新的版本,并且需要你有AutoLayout,TableView以及Swift 3的相關知識。
I have a Table, I have a View, hing ~ , TableView
不管是老司機還是新司機,日常開發中使用 UITableView 來搭建應用框架的肯定都遇到過這種尷尬:辣就是在剛入門iOS開發,相信絕大部分人針對接到產品狗要做動態列表或者有動態高度的列表需求時抽出過皮帶,因為那會兒主要都是手動計算,這種需求不僅費時費力,最后bug還多的一逼。
其實這種需求涉及到的技術最主要的無非就是Cell的自適應,俗話說的好,只要你掌握了 TableView ,大部分應用你是手到擒來的,對于TableView的基礎用法和復用早在12年就爛大街了,對于Cell自適應也都是老生常談,之所以還搞這種教程,完全是看著群里一幫傻屌每天都在無下限的討論一些恬不知恥的話題,Cell自適應就是重災區。對于網上的教程也好,開源庫也好,已經掌握的就趕緊滾犢子,不要浪費時間了。。。
開始吧
在喬幫主時代,那是的確沒辦法,基本上都是通過手動計算 Label 和各種可變動控件的高度,而且要是考慮屏幕旋轉,那就頭大咯,還好那會兒屏幕沒有太多尺寸。
步入庫克時代,大概蘋果的工程師也覺得手動計算麻煩的一逼,于是有了 AutoLayout 以及開放了新的Api。
Objective-C:
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize;
Swift:
funcsystemLayoutSizeFitting(_targetSize: CGSize) -> CGSize
利用此Api,無論你是代碼黨還是煞筆黨,配合 AutoLayout 就可以搞定Cell自適應的問題,可以說是載歌載舞啊。
現在,得益于 iOS8 對 Interface Builder 改進和 AutoLayout 的優化,只要是你的應用適配到 iOS8 以上,解決Cell自適應的問題那就So Easy!!!
那么接下來你需要搞定如下幾個簡單步驟:
- 使用 AutoLayout 創建你的TableView。
- 把 rowHeight 設置成 UITableViewAutomaticDimension 。
- 利用 estimatedRowHeight 設置一個預估高度或者自行實現預估高度的代理方法。
你先別逼逼問為什么要這么做,這是速成大法,先給你看效果才是最重要的,跟著做就行了,做完不懂再逼逼。。。
姿勢One:接需求
假設你有個煞筆客戶,要讓你做一個藝術家作品展示的應用,那么進入應用的第一個主頁面肯定是個藝術家信息列表,而且是動態列表。但是客戶需要的是快速實現,他不想聽你逼逼動態列表好不好做,也不想看你在那里煞筆的炫耀技術,你特么乖乖實現就行了。
你可以自己從頭搭建工程,當然考慮到看教程的大部分都是懶逼,這里給你們準備了一份初始工程,如果你不想搞事,勸你還是老實點用我這份比較好,Understand。。。
接下來我們就可以開始漲姿勢了,Let’s go…
姿勢Two:了解需求
由于我已經幫你模擬并拆解了需求,了解并分析你就免了,跟著看就成。。。
打開 Artistry 工程,找到 Views 分組,點開 Main.storyboard :
從左到右分別是:
- 作為根控制器的導航控制器。
- ArtistListViewController 負責顯示藝術家列表。
- ArtistDetailViewController 負責顯示藝術家作品以及詳情。
讓我們跑一盤,可以看到 ArtistListViewController 顯示了一個藝術家的列表,我們選擇第一個藝術家(Pablo Picasso),頁面跳轉到 ArtistDetailViewController 顯示藝術家作品介紹:
作為一個藝術家,不應該單單只有文字的介紹,還需要圖片,但是在這里我們并沒看到圖片信息,所以我們需要添加圖片顯示,那么由于圖片的寬高大小并不統一,因此你不可能只用一個固定高度就能解決,而是需要基于Cell內包含內容才決定的動態高度。
那么我們接下來就在 ArtistListViewController 利用動態高度實現Cell的自適應。
姿勢Three:Cell自適應
想要獲得Cell的正確高度,必須自定義一個Cell并且使用AutoLayout建立正確約束。
這里我們可以使用 Command + N 快捷鍵來創建文件,Cell是屬于視圖結構,因此最好是放到 Views 分組下,你要不喜歡可以隨便放,做項目要保持爛習慣也是你自己遭殃。
OK,這里我們選擇 Cocoa Touch Class 創建一個名為 ArtistTableViewCell 并且繼承自 UITableViewCell 的源文件。語言項肯定是整 Swift ,也不需要創建 Xib 可是文件哈,你踏馬要煞筆到懟Objc我也無話可說,那到這里我勸你趕緊Q掉。
打開我們剛才創建的 ArtistTableViewCell.swift 并刪掉系統自動生成的方法,接著我們添加如下屬性:
@IBOutlet weak var bioLabel: UILabel!
接著,點開 Main.storyboard ,在 ArtistListViewController 里選中 TableView 的 Cell ,在 Identity Inspector 就是識別檢查器, Command + Option + 3 也可以,都是一個屌意思,把 Class 欄修改為 ArtistTableViewCell 才能跟代碼綁定。
拖一個 UILabel 到剛才的 Cell 里,并把內容改為 Bio ,然后在 Attributes Inspector 屬性檢查器里把 Lines 設置為0,Label要是現實多行文字這個是必須的前提,OK,搞定之后看起就想這樣:
剛才我們設置的那個 Lines 也就是Label對應的斷行屬性 numberOfLines ,這個我就奶媽當到底吧,這個屬性是 Int 類型,設置幾就是只顯示幾行,設置 0 就是完整顯示,千萬別忘了設置,不然你就是當不插電開機的煞筆好了。
接下來在 Document Outline 找到剛才綁定的Cell上右鍵,在彈出的outlet彈出列表上把 ArtistTableViewCell 的屬性 bioLabel 拖到剛才弄的內容為 Bio 的Label上鏈接起來,演示如下:
是不是憋的一逼,一開始到現在咋都不說這么做是為啥,現在就告訴你為什么,讓 UITableViewCell 動態高度的秘訣是利用 AutoLayout 里有內建高度的控件比如 UILabel 這種來把Cell撐開,這種做法的前提就是必須把約束給設置完整,不然系統就沒法自動計算高度。
剛才原理都明白了我們可以給Label拉約束了,在Storyboard可視化界面的直接快捷添加,只需要讓 Label 的四邊頂住Cell的四邊即可,也就是給Label分別四個約束添加:
- leading
- top
- trailing
- bottom
關于 Constraints to margins 這個選項這里還是說一下,這個選項是留邊的做法,最開始是 Size Class 這個特性考慮不全,認為所有人都會為同一個應用在 Storyboard 里摻雜各種屏幕的頁面設計,也就是 iWatch 的誕生才引入的 Size Class 特性。
但是大部分日常開發都是基于iPhone,然后才是iPad,iWatch,所以這個作為默認勾選在iPhone上是很多新手踩的大坑,如果沒注意又不知道意思,勾選之后在不同屏幕上看到的邊緣就會有留邊或者被裁掉的問題。
所以在Xcode8.1之后如果是iPhone模板做頁面設計,是已經取消默認勾選。
所以根據你Xcode的版本,總之就是取消勾選個 Constraints to margins ,然后上下左右四個約束的約束值:
- 上下約束值為0
- 左右約束值為8
那么我們來驗證一下上面做的是否滿足AutoLayout的標準:
- 控件的起始點和寬高都能確定嗎?有上下左右四邊約束,這是絕逼能確定起始點和寬高的,通過。
- 可變控件是否把Cell的內容視圖 contentView 給頂住?Label上下兩邊的約束就足夠頂住,通過。
所以這個自動布局完全可以確定高度以便讓Cell高度自適應。
現在你的 ArtistTableViewCell 視圖已經搞定,讓我們跑一盤來看看:
不對啊,咋還是之前的屌樣,What the fuck!???莫緊張,我們只是弄了可視化綁定部分,你以為還真的全程可視化啊,當然還是寫點小代碼,別太天真了騷年!!!
來自:http://www.rockerhx.com/2016/12/12/2016-12-12-Self-sizing-Table-View-Cells/