swift中UITableView的使用(cell复用-自适应高度、headerView复用、footerView复用)

前端之家收集整理的这篇文章主要介绍了swift中UITableView的使用(cell复用-自适应高度、headerView复用、footerView复用)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

https://github.com/potato512/SYSwiftLearning

效果



  1. // MARK: - 数据
  2. func setLocalData()
  3. {
  4. self.mainArray = NSMutableArray()
  5. for number in 1...3
  6. {
  7. let rowArray:NSMutableArray = NSMutableArray()
  8. for numberTmp in 1...2
  9. {
  10. let model = CustomModel()
  11. model.title = "方法/步骤"
  12. model.content = "比如,我有一个ELCImagePickerController类,需要增加一个tag属性代码如下:软件基本信息。使用TableViewController自定义列表。版权声明:本文为博主原创文章,未经博主允许不得转载。swift自定义UITableViewCell,并配置到UITableView的注意事项"
  13. model.contentStatus = ((numberTmp % 2 == 0) ? true : false)
  14. rowArray.addObject(model)
  15. }
  16. let dict:NSMutableDictionary = NSMutableDictionary()
  17. // cell值
  18. dict.setObject(rowArray,forKey: "rowCell")
  19. // 页眉,页脚标题
  20. let numberTmp = random() % 1000 + number
  21. dict.setObject(String(format: "headerTitle:%@",arguments: [String(numberTmp)]),forKey: "rowHeader")
  22. dict.setObject(String(format: "footerTitle:%@",forKey: "rowFooter")
  23. // cell展开,或收起来状态
  24. dict.setObject(((number % 2 == 0) ? true : false),forKey: "rowStatus")
  25. self.mainArray.addObject(dict)
  26. }
  27. }
  1. // MARK: - 视图
  2. func setUI()
  3. {
  4. // 列表样式分plain,grouped,其中grouped在列表有页眉,页脚时会随cell滚动,而plain则是先固定后滚动
  5. self.mainTableView = UITableView(frame: self.view.bounds,style: UITableViewStyle.Grouped)
  6. self.view.addSubview(self.mainTableView)
  7. self.mainTableView.backgroundColor = UIColor.clearColor()
  8. self.mainTableView.delegate = self
  9. self.mainTableView.dataSource = self
  10. self.mainTableView.autoresizingMask = UIViewAutoresizing.FlexibleHeight
  11. self.mainTableView.tableFooterView = UIView()
  12. // 创建一个重用的页眉
  13. self.mainTableView!.registerClass(CustomHeader.self,forHeaderFooterViewReuseIdentifier: CustomHeaderIdentifier)
  14. // 创建一个重用的页脚
  15. self.mainTableView!.registerClass(CustomFooter.self,forHeaderFooterViewReuseIdentifier: CustomFooterIdentifier)
  16. // 创建一个重用的单元格
  17. self.mainTableView!.registerClass(CustomCell.self,forCellReuseIdentifier: CustomCellIdentifier)
  18. }
  1. // MARK: - UITableViewDataSource,UITableViewDelegate
  2. // 分组
  3. func numberOfSectionsInTableView(tableView: UITableView) -> Int {
  4. return self.mainArray.count
  5. }
  6. // MARK: 页眉视图
  7. func tableView(tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat {
  8. return CustomHeaderHeight
  9. }
  10. // func tableView(tableView: UITableView,titleForHeaderInSection section: Int) -> String? {
  11. //
  12. // let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  13. // let title:String! = dict.objectForKey("rowHeader") as! String
  14. //
  15. // return title
  16. // }
  17. // 自定义页眉(注意:自定义时,高度与代理方法中的高度一致,同时代理方法中的标题失效)
  18. func tableView(tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
  19. // 自定义视图,未复用
  20. /*
  21. let view = UIButton(frame: CGRectMake(0.0,0.0,CGRectGetWidth(self.mainTableView.frame),40.0))
  22. view.backgroundColor = UIColor.greenColor()
  23. view.contentHorizontalAlignment = .Center
  24. view.setTitleColor(UIColor.blackColor(),forState: .Normal)
  25. view.setTitleColor(UIColor.redColor(),forState: .Highlighted)
  26. // 响应事件,用于修改cell显示状态,即打开,或收起来
  27. view.tag = section
  28. view.addTarget(self,action: Selector("statusClick:"),forControlEvents: .TouchUpInside)
  29. let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  30. let title:String! = dict.objectForKey("rowHeader") as! String
  31. view.setTitle(title,forState: .Normal)
  32.  
  33. return view
  34. */
  35.  
  36. // 自定义视图,重用方法
  37. let headerView = CustomHeader(reuseIdentifier: CustomHeaderIdentifier)
  38. // 响应事件,用于修改cell显示状态,即打开,或收起来
  39. headerView.headerButton.tag = section
  40. headerView.headerButton.addTarget(self,forControlEvents: .TouchUpInside)
  41. // 标题
  42. let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  43. let title:String! = dict.objectForKey("rowHeader") as! String
  44. headerView.headerButton.setTitle(title,forState: .Normal)
  45.  
  46. return headerView
  47. }
  48. // MARK: 页脚视图
  49. func tableView(tableView: UITableView,heightForFooterInSection section: Int) -> CGFloat {
  50. return CustomFooterHeight
  51. }
  52. // func tableView(tableView: UITableView,titleForFooterInSection section: Int) -> String? {
  53. //
  54. // let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  55. // let title:String! = dict.objectForKey("rowFooter") as! String
  56. //
  57. // return title
  58. // }
  59. // 自定义页脚(注意:自定义时,高度与代理方法中的高度一致,同时代理方法中的标题失效)
  60. func tableView(tableView: UITableView,viewForFooterInSection section: Int) -> UIView? {
  61. // 自定义页脚视图,未重用
  62. /*
  63. let view = UILabel(frame: CGRectMake(0.0,40.0))
  64. view.backgroundColor = UIColor.yellowColor()
  65. view.textAlignment = .Center
  66. let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  67. let title:String! = dict.objectForKey("rowFooter") as! String
  68. view.text = title
  69. return view
  70. */
  71. // 自定义可重用页脚视图
  72. let footerView = CustomFooter(reuseIdentifier: CustomFooterIdentifier)
  73. let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  74. let title:String! = dict.objectForKey("rowFooter") as! String
  75. footerView.label.text = title
  76. return footerView
  77. }
  78. // MARK: cell单元格
  79. func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
  80. let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
  81. let status:Bool! = dict.objectForKey("rowStatus") as! Bool
  82. if status.boolValue
  83. {
  84. let array:NSArray! = dict.objectForKey("rowCell") as! NSArray
  85. return array.count
  86. }
  87. return 0
  88. }
  89. func tableView(tableView: UITableView,heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
  90. let dict:NSDictionary! = self.mainArray[indexPath.section] as! NSDictionary
  91. let array:NSArray! = dict.objectForKey("rowCell") as! NSArray
  92. let data:CustomModel! = array[indexPath.row] as! CustomModel
  93. let height = CustomCell.cellHeight(data)
  94. return height
  95. }
  96. func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  97. let dict:NSDictionary! = self.mainArray[indexPath.section] as! NSDictionary
  98. let array:NSArray! = dict.objectForKey("rowCell") as! NSArray
  99. let data:CustomModel! = array[indexPath.row] as! CustomModel
  100. let cell = CustomCell(model:data,cellIndex: indexPath,reuseIdentifier: CustomCellIdentifier)
  101. cell.contentButton.addTarget(self,action: Selector("buttonClick:"),forControlEvents: .TouchUpInside)
  102. return cell
  103. }
  104. func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) {
  105. tableView.deselectRowAtIndexPath(indexPath,animated: true)
  106. }
@H_404_28@// MARK: - click // statusClick func statusClick(button:UIButton) { let section = button.tag let dict:NSMutableDictionary! = self.mainArray[section] as! NSMutableDictionary let status:Bool! = dict.objectForKey("rowStatus") as! Bool dict.setObject((status.boolValue ? false : true),forKey: "rowStatus") self.mainArray.replaceObjectAtIndex(section,withObject: dict) self.mainTableView.reloadSections(NSIndexSet(index: section),withRowAnimation: .None) } // buttonClick func buttonClick(button:UIButton) { button.selected = !button.selected let indexPath = button.indexPath print("当前点击的按钮是:\(indexPath.section) + \(indexPath.row)") let dict:NSDictionary! = self.mainArray[indexPath.section] as! NSDictionary let array:NSArray! = dict.objectForKey("rowCell") as! NSArray let data:CustomModel! = array[indexPath.row] as! CustomModel let status:Bool! = data.contentStatus as Bool if status.boolValue { data.contentStatus = false } else { data.contentStatus = true } // 刷新数据,只刷新修改数据的信息 self.mainTableView.reloadRowsAtIndexPaths([indexPath],withRowAnimation: .None) // 刷新数据,刷新全部信息 // self.mainTableView.reloadData() }

自定义cell

  1. import UIKit
  2.  
  3.  
  4. // cell复用标识
  5. let CustomCellIdentifier = "CustomCell"
  6.  
  7. let width:CGFloat = UIScreen.mainScreen().bounds.width
  8. let contentFont:CGFloat = 12.0
  9.  
  10. // 默认高度
  11. let originXY = 10.0
  12. let labelHeight = 30.0
  13. let CustomCellHeightDefault = CGFloat(originXY + labelHeight + originXY + originXY + 0.0)
  14.  
  15. class CustomCell: UITableViewCell {
  16.  
  17. // 标题标签
  18. private var titleLabel:UILabel!
  19. // 详情按钮
  20. var contentButton:UIButton!
  21. // 显示或隐藏图标
  22. private var statusImage:UIImageView!
  23. // 副标题标签
  24. private var contentLabel:UILabel!
  25. // 消息数据结构
  26. var cellModel:CustomModel!
  27. private var cellIndex:NSIndexPath!
  28. override func awakeFromNib() {
  29. super.awakeFromNib()
  30. // Initialization code
  31. }
  32.  
  33. override func setSelected(selected: Bool,animated: Bool) {
  34. super.setSelected(selected,animated: animated)
  35.  
  36. // Configure the view for the selected state
  37. }
  38. // MARK: - 实例化方法
  39. required init?(coder aDecoder: NSCoder) {
  40. super.init(coder: aDecoder)
  41. }
  42. // 实例化cell
  43. init(model data:CustomModel,cellIndex index:NSIndexPath,reuseIdentifier cellId:String)
  44. {
  45. super.init(style: UITableViewCellStyle.Default,reuseIdentifier:cellId)
  46. // cell属性设置
  47. // self.selectionStyle = UITableViewCellSelectionStyle.None
  48. self.backgroundColor = UIColor.whiteColor()
  49. self.cellModel = data
  50. self.cellIndex = index
  51. self.setUI()
  52. self.showModel()
  53. }
  54. // 让单元格宽度始终为屏幕宽
  55. override var frame: CGRect
  56. {
  57. get
  58. {
  59. return super.frame
  60. }
  61. set (newFrame)
  62. {
  63. var frame = newFrame
  64. frame.size.width = width
  65. super.frame = frame
  66. }
  67. }
  68. // MARK: 视图
  69. func setUI()
  70. {
  71. // 10.0 + 40.0 + 10.0 + 10.0 + 自适应?(40.0)
  72. // 实例化
  73. if (self.titleLabel == nil)
  74. {
  75. self.titleLabel = UILabel(frame: CGRectZero)
  76. self.contentView.addSubview(self.titleLabel)
  77. self.titleLabel.textColor = UIColor.blackColor()
  78. self.titleLabel.font = UIFont.systemFontOfSize(14.0)
  79. }
  80. if (self.contentButton == nil)
  81. {
  82. self.contentButton = UIButton(type: .Custom)
  83. self.contentView.addSubview(self.contentButton)
  84. self.contentButton.backgroundColor = UIColor.orangeColor()
  85. self.contentButton.layer.cornerRadius = 5.0
  86. self.contentButton.layer.masksToBounds = true
  87. self.contentButton.titleLabel!.font = UIFont.systemFontOfSize(12.0)
  88. self.contentButton.setTitleColor(UIColor.redColor(),forState: .Highlighted)
  89. }
  90. if (self.statusImage == nil)
  91. {
  92. self.statusImage = UIImageView(frame: CGRectZero)
  93. self.contentView.addSubview(self.statusImage)
  94. self.statusImage.contentMode = .ScaleAspectFit
  95. }
  96. if (self.contentLabel == nil)
  97. {
  98. self.contentLabel = UILabel(frame: CGRectZero)
  99. self.contentView.addSubview(self.contentLabel)
  100. self.contentLabel.textColor = UIColor.brownColor()
  101. self.contentLabel.font = UIFont.systemFontOfSize(contentFont)
  102. self.contentLabel.numberOfLines = 0
  103. self.contentLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
  104. }
  105. // 设置frame
  106. // 标题
  107. self.titleLabel.frame = CGRectMake(CGFloat(originXY),CGFloat(originXY),(CGRectGetWidth(self.frame) - CGFloat(originXY) * 3 - 60.0),CGFloat(labelHeight))
  108. var currentView = self.titleLabel as UIView
  109. // 按钮
  110. self.contentButton.frame = CGRectMake((CGRectGetWidth(self.frame) - CGFloat(originXY) - 60.0),CGRectGetMinY(currentView.frame),60.0,CGRectGetHeight(currentView.frame))
  111. // 分割线
  112. let lineH = UIView(frame: CGRectMake(CGFloat(originXY),(CGRectGetMinY(currentView.frame) + CGRectGetHeight(currentView.frame) + CGFloat(originXY) - 0.5),(CGRectGetWidth(self.frame) - CGFloat(originXY) * 2),0.5))
  113. self.contentView.addSubview(lineH)
  114. lineH.backgroundColor = UIColor.lightGrayColor()
  115. // 状态图标
  116. self.statusImage.frame = CGRectMake(CGRectGetMinX(currentView.frame),(CGRectGetMinY(currentView.frame) + CGRectGetHeight(currentView.frame) + CGFloat(originXY)),CGFloat(originXY))
  117. currentView = self.statusImage as UIView
  118. // 详情
  119. self.contentLabel.frame = CGRectMake(CGFloat(originXY),(CGRectGetMinY(currentView.frame) + CGRectGetHeight(currentView.frame)),(width - CGFloat(originXY) * 2),0.0)
  120. }
  121. // MARK: 数据处理
  122. func showModel()
  123. {
  124. self.titleLabel.text = self.cellModel.title
  125. self.contentLabel.text = self.cellModel.content
  126. self.contentButton.indexPath = self.cellIndex
  127. let status = self.cellModel.contentStatus
  128. if status.boolValue
  129. {
  130. self.contentButton.setTitle("隐藏详情",forState: .Normal)
  131. self.contentButton.setTitleColor(UIColor.blueColor(),forState: .Normal)
  132. self.statusImage.image = UIImage(named: "statusDown_image")
  133. // 计算字生符串的宽度,高度
  134. var rect = self.contentLabel.frame
  135. let height = CustomCell.heightWithText(self.cellModel.content)
  136. rect.size.height = height
  137. self.contentLabel.frame = rect
  138. }
  139. else
  140. {
  141. self.contentButton.setTitle("显示详情",forState: .Normal)
  142. self.contentButton.setTitleColor(UIColor.blackColor(),forState: .Normal)
  143. self.statusImage.image = UIImage(named: "statusUp_image")
  144. // 隐藏
  145. var rect = self.contentLabel.frame
  146. rect.size.height = 0.0
  147. self.contentLabel.frame = rect
  148. }
  149. }
  150. // MARK: - 计算高度
  151. class func cellHeight(model:CustomModel) -> CGFloat
  152. {
  153. let status = model.contentStatus
  154. if status.boolValue
  155. {
  156. let height = self.heightWithText(model.content)
  157. return CustomCellHeightDefault + height
  158. }
  159. else
  160. {
  161. return CustomCellHeightDefault
  162. }
  163. }
  164. private class func heightWithText(text:String) -> CGFloat
  165. {
  166. let size:CGRect = text.boundingRectWithSize(CGSizeMake(width,999.9),options: NSStringDrawingOptions.UsesLineFragmentOrigin,attributes: [NSFontAttributeName:UIFont.systemFontOfSize(contentFont)],context: nil)
  167. return size.height
  168. }
  169. }

自定义headerView

  1. import UIKit
  2.  
  3. let CustomHeaderHeight:CGFloat = 40.0
  4. let CustomHeaderIdentifier = "CustomHeader"
  5. let CustomHeaderWidth:CGFloat = UIScreen.mainScreen().bounds.width
  6.  
  7. class CustomHeader: UITableViewHeaderFooterView {
  8.  
  9. // 标题按钮
  10. var headerButton:UIButton!
  11. // 必须实现的方法
  12. required init?(coder aDecoder: NSCoder) {
  13. fatalError("init(coder:) has not been implemented")
  14. }
  15. // 实例化
  16. override init(reuseIdentifier: String?)
  17. {
  18. super.init(reuseIdentifier: reuseIdentifier)
  19. self.setUI()
  20. }
  21. // 让单元格宽度始终为屏幕宽
  22. override var frame: CGRect
  23. {
  24. get
  25. {
  26. return super.frame
  27. }
  28. set (newFrame)
  29. {
  30. var frame = newFrame
  31. frame.size.width = CustomHeaderWidth
  32. super.frame = frame
  33. }
  34. }
  35.  
  36. // 视图
  37. private func setUI()
  38. {
  39. if self.headerButton == nil
  40. {
  41. self.headerButton = UIButton(frame: CGRectMake(0.0,CustomHeaderWidth,CustomHeaderHeight))
  42. self.contentView.addSubview(self.headerButton)
  43. self.headerButton.backgroundColor = UIColor.greenColor()
  44. self.headerButton.contentHorizontalAlignment = .Center
  45. self.headerButton.setTitleColor(UIColor.blackColor(),forState: .Normal)
  46. self.headerButton.setTitleColor(UIColor.redColor(),forState: .Highlighted)
  47. }
  48. }
  49.  
  50. }

自定义footerView

  1. import UIKit
  2.  
  3. let CustomFooterHeight:CGFloat = 40.0
  4. let CustomFooterIdentifier = "CustomFooter"
  5. let CustomFooterWidth:CGFloat = UIScreen.mainScreen().bounds.width
  6.  
  7. class CustomFooter: UITableViewHeaderFooterView {
  8.  
  9. var label:UILabel!
  10. // 必须实现
  11. required init?(coder aDecoder: NSCoder) {
  12. fatalError("init(coder:) has not been implemented")
  13. }
  14. // 实例化
  15. override init(reuseIdentifier: String?)
  16. {
  17. super.init(reuseIdentifier: reuseIdentifier)
  18. self.setUI()
  19. }
  20.  
  21. // 视图
  22. private func setUI()
  23. {
  24. if self.label == nil
  25. {
  26. self.label = UILabel(frame: CGRectMake(0.0,CustomFooterWidth,CustomFooterHeight))
  27. self.contentView.addSubview(self.label)
  28. self.label.font = UIFont.systemFontOfSize(10.0)
  29. self.label.textAlignment = .Center
  30. self.label.backgroundColor = UIColor.yellowColor()
  31. }
  32. }
  33. }

自定义model

  1. import UIKit
  2.  
  3. class CustomModel: NSObject {
  4.  
  5. // 标题
  6. var title:String!
  7. // 内容
  8. var content:String!
  9. // 内容显示,或隐藏状态
  10. var contentStatus:Bool!
  11. }

猜你在找的Swift相关文章