1. 程式人生 > >[Swift通天遁地]二、表格表單-(3)在表格中嵌套另一個表格並使Cell的高度自適應

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

works uiview 添加 comm exe bounds tro enc 表格

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

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

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

【Class】:CustomizeUITableViewCell ,類名。

【Subclass of】:UITableViewCell ,父類

【Language】:Swift

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

現在開始編寫代碼,創建一個自定義的單元格的類。

  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 }

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