iOS回顧筆記(08) -- 自定義Cell的類型和創建步驟總結



iOS回顧筆記(08) -- 自定義Cell的類型和創建步驟總結

項目中我們常見的自定義cell主要分為兩種

  • 等高cell:
    如應用列表、功能列表

  • 非等高cell:
    如微博列表、QQ聊天頁面

下面對這兩類cell的創建方式簡單記錄各步驟。

等高Cell

等高cell通常有三種創建方式:

  • storyboard自定義cell
  • xib自定義cell
  • 代碼創建cell(使用frame計算/使用Autolayout布局)

下面分別記錄每種創建步驟:

1. storyboard自定義cell

  • 1.創建一個繼承自UITableViewCell的子類,比如XYDealCell

  • 2.在storyboard中

    • 往cell里面增加需要用到的子控件

    • 設置cell的重用標識

    • 設置cell的class為XYDealCell

  • 3.在控制器中

    • 利用重用標識找到cell
    • 給cell傳遞模型數據
  • 4.在XYDealCell中

    • 將storyboard中的子控件連線到類擴展中
    • 需要提供一個模型屬性,重寫模型的set方法,在這個方法中設置模型數據到子控件上
       

       

2.xib自定義cell

  • 1.創建一個繼承自UITableViewCell的子類,比如XYDealCell
  • 2.創建一個xib文件(文件名建議跟cell的類名一樣),比如XYDealCell.xib
    • 拖拽一個UITableViewCell出來
    • 修改cell的class為XYDealCell
    • 設置cell的重用標識
    • 往cell中添加需要用到的子控件
  • 3.在控制器中
    • 利用registerNib...方法注冊xib文件
    • 利用重用標識找到cell(如果沒有注冊xib文件,就需要手動去加載xib文件)
    • 給cell傳遞模型數據
  • 4.在XYDealCell中
    • 將xib中的子控件連線到類擴展中
    • 需要提供一個模型屬性,重寫模型的set方法,在這個方法中設置模型數據到子控件上
    • 也可以將創建獲得cell的代碼封裝起來(比如cellWithTableView:方法)

 

3.代碼自定義cell(使用frame)

  • 1.創建一個繼承自UITableViewCell的子類,比如XYDealCell
    • 在initWithStyle:reuseIdentifier:方法中
      • 添加子控件
      • 設置子控件的初始化屬性(比如文字顏色、字體)
    • 在layoutSubviews方法中設置子控件的frame
    • 需要提供一個模型屬性,重寫模型的set方法,在這個方法中設置模型數據到子控件
  • 2.在控制器中
    • 利用registerClass...方法注冊XYDealCell類
    • 利用重用標識找到cell(如果沒有注冊類,就需要手動創建cell)
    • 給cell傳遞模型數據
    • 也可以將創建獲得cell的代碼封裝起來(比如cellWithTableView:方法)

 

4.代碼自定義cell(使用autolayout)

  • 1.創建一個繼承自UITableViewCell的子類,比如XYDealCell
    • 在initWithStyle:reuseIdentifier:方法中
      • 添加子控件
      • 添加子控件的約束(建議使用Masonry
      • 設置子控件的初始化屬性(比如文字顏色、字體)
    • 需要提供一個模型屬性,重寫模型的set方法,在這個方法中設置模型數據到子控件
  • 2.在控制器中
    • 利用registerClass...方法注冊XYDealCell類
    • 利用重用標識找到cell(如果沒有注冊類,就需要手動創建cell)
    • 給cell傳遞模型數據
    • 也可以將創建獲得cell的代碼封裝起來(比如cellWithTableView:方法)

非等高cell

  • xib自定義cell(重點)
    • 在模型中增加一個cellHeight屬性,用來存放對應cell的高度
    • 在cell的模型屬性set方法中調用[self layoutIfNeed]方法強制布局,然后計算出模型的cellheight屬性值
    • 在控制器中實現tableView:estimatedHeightForRowAtIndexPath:方法,返回一個估計高度,比如200
    • 在控制器中實現tableView:heightForRowAtIndexPath:方法,返回cell的真實高度(模型中的cellHeight屬性)
  • storyboard自定義cell
  • 代碼自定義cell(frame)
  • 代碼自定義cell(Autolayout)

非等高Cell的幾個小重點知識

1. tableview返回行高的方法

/**
 *  精確返回每行cell的高度,此方法會真實計算對應高度值,並會一次性算出所有行高
 */
 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100;
}

/**
 *  估測返回每行cell的高度,添加此方法可以修改調用順序,不進行一次性精確計算,先返回cell,在根據每行的展示計算對應真實高度,用到哪個算哪個,提高性能
 */
  - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
    return 200;
}

如果直接調用計算行高方法

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

程序的調用順序是

  1. 調用heightForRowAtIndexPath返回所有行高
  2. 調用cellForRowAtIndexPath返回對應行

如果先調用估算高度方法

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

程序的調用順序是

  1. 調用estimatedHeightForRowAtIndexPath返回所有行高
  2. 調用cellForRowAtIndexPath返回對應行
  3. 調用cellForRowAtIndexPath返回對應的真實行高

所以使用估算行高的方法可提高效率。

【注意】

經過iOS 11適配的測試發現:add time:2017年12月07日17:56:03

iOS 11 中tableViewCell的高度計算順序發生變化

iOS 11 中數據源方法的調用順序(無論有沒有估算高度都是直接先執行cellForRow)
estimatedHeightForRow --> cellForRow -- > heightForRow 或
cellForRow -- > heightForRow

iOS 10 以下有沒有估算高度是不同的
estimatedHeightForRow --> cellForRow -- > heightForRow
heightForRow -- > cellForRow

2. 強制布局方法 : [cell layoutIfNeeded];

  • 當cell調用setModel方法后,雖已賦值,但cell尚未展示。所以系統不會根據約束進行布局。所以此時無法得到cell真實的frame等數值。

  • [cell layoutIfNeeded]就是在給cell賦值之后調用,強制進行布局,可得到cell真實的frame值

3. UILabel限制最大高度 : preferredMaxLayoutWidth

  • UILabel在自動布局時比較特殊。系統會自動根據內容計算它的寬高,所以只需設置位置約束就行系統自動計算UILabel的寬高時,會默認完全包裹其內部的文字內容:
  • 為防止系統自動計算Label高度時候,按照完全包裹內容,所以需要在Label創建完之后明確設置Label的自動布局最大寬度,如下方法:
 - (void)awakeFromNib
{
    // 設置自己的昵稱Label的最大自動布局的寬度為 cell 的寬度減去 20
    self.nameLabel.preferredMaxLayoutWidth = self.bounds.size.width - 20;
}

小結

  • 項目中cell類型常見有兩種:等高cell 和 非等高cell
  • 等高cell自定義,由於不用關心高度計算問題、推薦使用Xib、StoryBoard。
  • 非等高cell自定義,推薦使用Xib。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM