★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(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 }