[Swift通天遁地]2、表格表單-(3)在表格中嵌套另外一個表格並使Cell的高度自適應

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-yreaprjk-kd.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

目錄:[Swift]通天遁地Swiftgit

本文將演示如何在表格中嵌套另外一個表格並使Cell的高度自適應,建立更增強大的佈局效果。github

在項目文件夾【DemoApp】上點擊鼠標右鍵,彈出右鍵菜單。swift

【New File】->【Cocoa Touch Class】->【Next】->數組

【Class】:CustomizeUITableViewCell ,類名。微信

【Subclass of】:UITableViewCell ,父類ide

【Language】:Swift佈局

->【Next】->【Create】
在項目導航區,打開剛剛建立的代碼文件【CustomizeUITableViewCell.swift】post

如今開始編寫代碼,建立一個自定義的單元格的類。字體

  1 import UIKit
  2 
  3 //引入須要遵循的表格視圖的相關協議UITableViewDataSource, UITableViewDelegate
  4 class CustomizeUITableViewCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {
  5     
  6     //添加兩個屬性:
  7     //1.表格對象
  8     var tableView : UITableView!;
  9     //2.數據來源
 10     var comments : [String] = []
 11     
 12     //重寫單元格的初始化方法,在該方法中對單元格進行自定義操做
 13     override init(style: UITableViewCellStyle, reuseIdentifier: String?)
 14     {
 15         //首先實現父類的初始化方法
 16         super.init(style: style, reuseIdentifier: reuseIdentifier);
 17         
 18         //初始化一個表格對象,並設置表格對象的顯示區域
 19         tableView = UITableView(frame: CGRect(x: 20, y: 0, width: 280, height: 90))
 20         //設置表格對象的數據源爲當前的視圖控制器對象
 21         tableView.dataSource = self
 22         //設置表格對象的代理爲當前的視圖控制器對象
 23         tableView.delegate = self
 24         //設置不容許內部表格的滾動,
 25         //只容許單元格所屬表格能夠進行滾動
 26         tableView.isScrollEnabled = false;
 27         
 28         //將表格視圖添加到根視圖中
 29         self.addSubview(tableView)
 30     }
 31     
 32     //添加一個代理方法,用來設置表格的行數
 33     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
 34     {
 35         //在此設置表格的行數,與數組的長度保持一致
 36         return comments.count
 37     }
 38     
 39     //添加一個代理方法,用來初始化或複用表格中的單元格
 40     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
 41     {
 42         //建立一個字符串常量,做爲單元格的複用標識
 43         let identifier = "reusedCell"
 44         //根據複用標識,從表格中得到能夠複用的單元格
 45         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
 46         
 47         //若是沒有能夠複用的單元格
 48         if(cell == nil)
 49         {
 50             //則初始化一個默認樣式的單元格,並設置單元格的複用標識
 51             cell = UITableViewCell(style: UITableViewCellStyle.default,
 52                                    reuseIdentifier: identifier)
 53         }
 54         
 55         //從數組中得到指定序號的字符串,做爲單元格的標題文字。
 56         cell?.textLabel?.text = comments[(indexPath as NSIndexPath).row]
 57         //設置標題文字的字體大小爲12
 58         cell?.textLabel?.font = UIFont.systemFont(ofSize: 12)
 59         //設置文字的顏色爲灰色
 60         cell?.textLabel?.textColor = UIColor.gray
 61         //設置標籤可顯示多行文字
 62         cell?.textLabel?.numberOfLines = 0;
 63         
 64         return cell!
 65     }
 66     
 67     //建立一個類方法,用來根據字符串的長度,計算單元格的高度
 68     class func caculateCellHeight(comment:String)->CGFloat
 69     {
 70         //建立一個字體常量,和單元格的字體大小相同
 71         let font = UIFont.systemFont(ofSize: 12)
 72         //經過計算得到文字的顯示區域
 73         let size = comment.boundingRect(with: CGSize(), 
 74                                         options: .usesFontLeading, 
 75                                         attributes: [NSFontAttributeName:font],
 76                                         context: nil);
 77         
 78         //經過顯示區域的高度,減去文字至基線的距離,得到文字的高度。
 79         //將顯示區域的寬度,除以每行文字的寬度,得到文字的行數,二者相乘得到總的高度。
 80         return (size.height-2*size.origin.y)*(size.width/280.0)
 81     }
 82     
 83     //添加一個代理方法,用來設置單元格的高度
 84     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)-> CGFloat
 85     {
 86         //根據單元格的序號,得到該單元格將要顯示的字符串
 87         let subComments = comments[(indexPath as NSIndexPath).row]
 88         //根據剛剛建立的類方法,計算單元格容納該字符串所需的高度
 89         let cellHeight =  CustomizeUITableViewCell.caculateCellHeight(comment:subComments)
 90         //而後進行臨界判斷,從而將高度數值保持在一個合理的範圍以內。
 91         if(cellHeight < 30)
 92         {
 93             return 30
 94         }
 95         else
 96         {
 97             return cellHeight
 98         }
 99     }
100     
101     //添加一個方法,用來設置表格的數據源。該方法將在外部的表格中被調用。
102     func setCommentsForTable(_ comments:[String])
103     {
104         //設置自定義單元格的數組屬性,做爲該單元格的表格的數據源。
105         self.comments = comments
106         
107         //計算單元格內部的表格的高度
108         //首先初始化一個浮點常量
109         var tableHeight:CGFloat = 0
110         //建立一個循環,遍歷表格的數據源。
111         //經過對每一個單元格的高度進行累計,合計整個表格的高度。
112         for i in 0 ..< comments.count
113         {
114             tableHeight += CustomizeUITableViewCell.caculateCellHeight(comment:comments[i])
115         }
116         
117         //從新繪製表格的顯示區域
118         tableView.frame = CGRect(x: 20, y: 0, width: 280, height: tableHeight + 20)
119         //並刷新表格中的數據
120         tableView.reloadData()
121     }
122     
123     //添加一個方法,用來得到單元格內部表格的高度數值
124     func getMyHeight()->CGFloat
125     {
126        //用來得到單元格內部表格的高度數值
127         return tableView.frame.size.height
128     }
129     
130     //最後添加一個必須實現的初始化方法
131     required init(coder aDecoder: NSCoder)
132     {
133         fatalError("init(code:)has not brrn implomented");
134     }
135 }

在項目導航區,打開視圖控制器的代碼文件【ViewController.swift】

如今開始建立處於外部的表格視圖,並在表格中使用剛剛自定義的包含表格的單元格。

  1 import UIKit
  2 
  3 //使當前的視圖控制器類,遵循表格的數據源協議UITableViewDataSource和代理協議UITableViewDelegate
  4 class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
  5     
  6     //建立一個數組,做爲新聞的標題。
  7     var articles = ["SpaceX wants to launch 4,425 satellites", 
  8     "Free Workshop in Los Angeles, December 10!", 
  9     "Stephen Hawking just gave humanity a due date for finding another planet"]
 10     //建立另外一個二維數組,做爲新聞的評論內容。
 11     var comments = [["1.Elon Musk's SpaceX wants to launch thousands of satellites into space with the aim of providing super-fast global internet coverage, according to a regulatory filing.","2.SpaceX – the company on a mission to colonize Mars – outlined plans to put 4,425 satellites into space in a Federal Communications Commission (FCC) filing from earlier this week.","3.Billionaire Musk – who is also the chief executive of electric car company Tesla – first announced plans for the project in 2015, with an estimated cost of $10 billion."],["1.Join us for a free Rich Dad Education financial workshop in Los Angeles.","2.All attendees are entered to win a tablet. Save your spot now!","3.Dream of working in Australia?"],["1.If humanity survives the rise of artificial intelligence, the ravages of climate change and the threat of nuclear terrorism in the next century, it doesn't mean we're home free, according to Stephen Hawking.","2.The renowned theoretical physicist has gone as far as providing humanity with a deadline for finding another planet to colonize: We have 1,000 years.","3.Remaining on Earth any longer, Hawking believes, places humanity at great risk of encountering another mass extinction."]]
 12     
 13     override func viewDidLoad() {
 14         super.viewDidLoad()
 15         // Do any additional setup after loading the view, typically from a nib.
 16         
 17         //得到設備的屏幕尺寸
 18         let screenRect = UIScreen.main.bounds
 19         //建立一個矩形區域,做爲表格視圖的顯示區域
 20         let tableRect = CGRect(x: 0,
 21                                y: 20,
 22                                width: screenRect.size.width,
 23                                height: screenRect.size.height - 20)
 24         //初始化一個指定顯示區域的表格對象
 25         let tableView = UITableView(frame: tableRect)
 26         
 27         //設置表格對象的數據源爲當前的視圖控制器對象
 28         tableView.dataSource = self
 29         //設置表格對象的代理爲當前的視圖控制器對象
 30         tableView.delegate = self
 31         
 32         //設置單元格的分隔線爲空白
 33         tableView.separatorStyle = UITableViewCellSeparatorStyle.none
 34         //將表格視圖添加到根視圖中
 35         self.view.addSubview(tableView)
 36     }
 37     
 38     //添加一個代理方法,用來設置表格的行數
 39     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
 40     {
 41         //在此設置表格的行數爲新聞標題數組長度的兩倍。
 42         //偶數行用來顯示標題,奇數行用來顯示評論
 43         return articles.count * 2
 44     }
 45     
 46     //添加一個代理方法,用來初始化或複用表格中的單元格
 47     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)-> UITableViewCell
 48     {
 49         //建立兩個字符串常量,做爲單元格的複用標識
 50         //1.用於顯示新聞標題的偶數行單元格
 51         let cellForArticle = "cellForArticle"
 52         //2.用於顯示新聞評論的奇數行的自定義單元格
 53         let cellForComments = "cellForComments"
 54         
 55         //建立兩個單元格對象
 56         //1.系統默認樣式的單元格
 57         var cell1:UITableViewCell?;
 58         //2.包含子表格的自定義單元格
 59         var cell2:CustomizeUITableViewCell?;
 60         
 61         //判斷偶數行
 62         if (indexPath as NSIndexPath).row % 2 == 0
 63         {
 64             //根據偶數行的複用標識,從表格中得到能夠複用的單元格
 65             cell1 = tableView.dequeueReusableCell(withIdentifier: cellForArticle)
 66             //若是沒有能夠複用的單元格
 67             if cell1 == nil
 68             {
 69                 //則初始化一個默認樣式的單元格,並設置單元格的複用標識
 70                 cell1 = UITableViewCell(style: UITableViewCellStyle.default,
 71                                         reuseIdentifier: cellForArticle)
 72             }
 73             
 74             //設置單元格的標題文字爲新聞的標題
 75             cell1?.textLabel?.text = articles[(indexPath as NSIndexPath).row/2]
 76             //設置標題文字的字體大小爲14
 77             cell1?.textLabel?.font = UIFont.systemFont(ofSize: 14)
 78             //設置文字的顏色爲白色
 79             cell1?.textLabel?.textColor = UIColor.white
 80             //設置單元格的背景顏色爲橙色
 81             cell1?.backgroundColor = UIColor.orange
 82             
 83             //返回設置好的偶數行單元格
 84             return cell1!
 85         }
 86         else
 87         {
 88             //處理奇數行的單元格
 89              //根據奇數行的複用標識,從表格中得到能夠複用的單元格
 90             cell2 = tableView.dequeueReusableCell(withIdentifier: cellForComments) as? CustomizeUITableViewCell
 91             //若是沒有能夠複用的單元格
 92             if cell2 == nil
 93             {
 94                 //則初始化一個默認樣式的單元格,並設置單元格的複用標識
 95                 cell2 = CustomizeUITableViewCell(style: UITableViewCellStyle.default,
 96                                                  reuseIdentifier: cellForComments)
 97             }
 98             
 99             //從數組中得到該單元格將要顯示的文字內容
100             let subComments = comments[(indexPath as NSIndexPath).row/2]
101             //而後調用自定義單元格對象的,設置子表格的數據源的方法,
102             //在設置子表格數據源的同時,也使子表格的高度作到自適應。
103             cell2?.setCommentsForTable(subComments)
104             
105             //返回奇數行的單元格
106             return cell2!
107         }
108     }
109     
110     //添加一個代理方法,用來設置單元格的高度
111     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
112     {
113         //若是是偶數行的單元格,則設置高度爲40
114         if (indexPath as NSIndexPath).row % 2 == 0
115         {
116             return 40
117         }
118         else
119         {
120             //處理奇數行單元格的狀況
121             //得到該單元格中的全部文字
122             let subComments = comments[(indexPath as NSIndexPath).row/2]
123             //初始化一個浮點數的變量,用來合計單元格的高度
124             var cellHeight:CGFloat = 0
125             //此處經過相同的方式
126             for i in 0 ..< subComments.count
127             {
128                 //經過累加的方式計算子表格的高度
129                 cellHeight += CustomizeUITableViewCell.caculateCellHeight(comment: subComments[i])
130             }
131 
132             //最後返回該高度與20的和,避免單元格中的文字過於擁擠
133             return cellHeight + 20
134         }
135     }
136     
137     override func didReceiveMemoryWarning() {
138         super.didReceiveMemoryWarning()
139         // Dispose of any resources that can be recreated.
140     }
141 }
相關文章
相關標籤/搜索