https://github.com/potato512/SYSwiftLearning
效果图
- // MARK: - 数据
- func setLocalData()
- {
- self.mainArray = NSMutableArray()
- for number in 1...3
- {
- let rowArray:NSMutableArray = NSMutableArray()
- for numberTmp in 1...2
- {
- let model = CustomModel()
- model.title = "方法/步骤"
- model.content = "比如,我有一个ELCImagePickerController类,需要增加一个tag属性,代码如下:软件基本信息。使用TableViewController自定义列表。版权声明:本文为博主原创文章,未经博主允许不得转载。swift自定义UITableViewCell,并配置到UITableView的注意事项"
- model.contentStatus = ((numberTmp % 2 == 0) ? true : false)
- rowArray.addObject(model)
- }
- let dict:NSMutableDictionary = NSMutableDictionary()
- // cell值
- dict.setObject(rowArray,forKey: "rowCell")
- // 页眉,页脚标题
- let numberTmp = random() % 1000 + number
- dict.setObject(String(format: "headerTitle:%@",arguments: [String(numberTmp)]),forKey: "rowHeader")
- dict.setObject(String(format: "footerTitle:%@",forKey: "rowFooter")
- // cell展开,或收起来状态
- dict.setObject(((number % 2 == 0) ? true : false),forKey: "rowStatus")
- self.mainArray.addObject(dict)
- }
- }
- // MARK: - 视图
- func setUI()
- {
- // 列表样式分plain,grouped,其中grouped在列表有页眉,页脚时会随cell滚动,而plain则是先固定后滚动
- self.mainTableView = UITableView(frame: self.view.bounds,style: UITableViewStyle.Grouped)
- self.view.addSubview(self.mainTableView)
- self.mainTableView.backgroundColor = UIColor.clearColor()
- self.mainTableView.delegate = self
- self.mainTableView.dataSource = self
- self.mainTableView.autoresizingMask = UIViewAutoresizing.FlexibleHeight
- self.mainTableView.tableFooterView = UIView()
- // 创建一个重用的页眉
- self.mainTableView!.registerClass(CustomHeader.self,forHeaderFooterViewReuseIdentifier: CustomHeaderIdentifier)
- // 创建一个重用的页脚
- self.mainTableView!.registerClass(CustomFooter.self,forHeaderFooterViewReuseIdentifier: CustomFooterIdentifier)
- // 创建一个重用的单元格
- self.mainTableView!.registerClass(CustomCell.self,forCellReuseIdentifier: CustomCellIdentifier)
- }
@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() }
- // MARK: - UITableViewDataSource,UITableViewDelegate
- // 分组
- func numberOfSectionsInTableView(tableView: UITableView) -> Int {
- return self.mainArray.count
- }
- // MARK: 页眉视图
- func tableView(tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat {
- return CustomHeaderHeight
- }
- // func tableView(tableView: UITableView,titleForHeaderInSection section: Int) -> String? {
- //
- // let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- // let title:String! = dict.objectForKey("rowHeader") as! String
- //
- // return title
- // }
- // 自定义页眉(注意:自定义时,高度与代理方法中的高度一致,同时代理方法中的标题失效)
- func tableView(tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
- // 自定义视图,未复用
- /*
- let view = UIButton(frame: CGRectMake(0.0,0.0,CGRectGetWidth(self.mainTableView.frame),40.0))
- view.backgroundColor = UIColor.greenColor()
- view.contentHorizontalAlignment = .Center
- view.setTitleColor(UIColor.blackColor(),forState: .Normal)
- view.setTitleColor(UIColor.redColor(),forState: .Highlighted)
- // 响应事件,用于修改cell显示状态,即打开,或收起来
- view.tag = section
- view.addTarget(self,action: Selector("statusClick:"),forControlEvents: .TouchUpInside)
- let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- let title:String! = dict.objectForKey("rowHeader") as! String
- view.setTitle(title,forState: .Normal)
- return view
- */
- // 自定义视图,重用方法
- let headerView = CustomHeader(reuseIdentifier: CustomHeaderIdentifier)
- // 响应事件,用于修改cell显示状态,即打开,或收起来
- headerView.headerButton.tag = section
- headerView.headerButton.addTarget(self,forControlEvents: .TouchUpInside)
- // 标题
- let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- let title:String! = dict.objectForKey("rowHeader") as! String
- headerView.headerButton.setTitle(title,forState: .Normal)
- return headerView
- }
- // MARK: 页脚视图
- func tableView(tableView: UITableView,heightForFooterInSection section: Int) -> CGFloat {
- return CustomFooterHeight
- }
- // func tableView(tableView: UITableView,titleForFooterInSection section: Int) -> String? {
- //
- // let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- // let title:String! = dict.objectForKey("rowFooter") as! String
- //
- // return title
- // }
- // 自定义页脚(注意:自定义时,高度与代理方法中的高度一致,同时代理方法中的标题失效)
- func tableView(tableView: UITableView,viewForFooterInSection section: Int) -> UIView? {
- // 自定义页脚视图,未重用
- /*
- let view = UILabel(frame: CGRectMake(0.0,40.0))
- view.backgroundColor = UIColor.yellowColor()
- view.textAlignment = .Center
- let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- let title:String! = dict.objectForKey("rowFooter") as! String
- view.text = title
- return view
- */
- // 自定义可重用页脚视图
- let footerView = CustomFooter(reuseIdentifier: CustomFooterIdentifier)
- let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- let title:String! = dict.objectForKey("rowFooter") as! String
- footerView.label.text = title
- return footerView
- }
- // MARK: cell单元格
- func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
- let dict:NSDictionary! = self.mainArray[section] as! NSDictionary
- let status:Bool! = dict.objectForKey("rowStatus") as! Bool
- if status.boolValue
- {
- let array:NSArray! = dict.objectForKey("rowCell") as! NSArray
- return array.count
- }
- return 0
- }
- func tableView(tableView: UITableView,heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
- 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 height = CustomCell.cellHeight(data)
- return height
- }
- func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
- 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 cell = CustomCell(model:data,cellIndex: indexPath,reuseIdentifier: CustomCellIdentifier)
- cell.contentButton.addTarget(self,action: Selector("buttonClick:"),forControlEvents: .TouchUpInside)
- return cell
- }
- func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) {
- tableView.deselectRowAtIndexPath(indexPath,animated: true)
- }
自定义cell
- import UIKit
- // cell复用标识
- let CustomCellIdentifier = "CustomCell"
- let width:CGFloat = UIScreen.mainScreen().bounds.width
- let contentFont:CGFloat = 12.0
- // 默认高度
- let originXY = 10.0
- let labelHeight = 30.0
- let CustomCellHeightDefault = CGFloat(originXY + labelHeight + originXY + originXY + 0.0)
- class CustomCell: UITableViewCell {
- // 标题标签
- private var titleLabel:UILabel!
- // 详情按钮
- var contentButton:UIButton!
- // 显示或隐藏图标
- private var statusImage:UIImageView!
- // 副标题标签
- private var contentLabel:UILabel!
- // 消息数据结构
- var cellModel:CustomModel!
- private var cellIndex:NSIndexPath!
- override func awakeFromNib() {
- super.awakeFromNib()
- // Initialization code
- }
- override func setSelected(selected: Bool,animated: Bool) {
- super.setSelected(selected,animated: animated)
- // Configure the view for the selected state
- }
- // MARK: - 实例化方法
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- }
- // 实例化cell
- init(model data:CustomModel,cellIndex index:NSIndexPath,reuseIdentifier cellId:String)
- {
- super.init(style: UITableViewCellStyle.Default,reuseIdentifier:cellId)
- // cell属性设置
- // self.selectionStyle = UITableViewCellSelectionStyle.None
- self.backgroundColor = UIColor.whiteColor()
- self.cellModel = data
- self.cellIndex = index
- self.setUI()
- self.showModel()
- }
- // 让单元格宽度始终为屏幕宽
- override var frame: CGRect
- {
- get
- {
- return super.frame
- }
- set (newFrame)
- {
- var frame = newFrame
- frame.size.width = width
- super.frame = frame
- }
- }
- // MARK: 视图
- func setUI()
- {
- // 10.0 + 40.0 + 10.0 + 10.0 + 自适应?(40.0)
- // 实例化
- if (self.titleLabel == nil)
- {
- self.titleLabel = UILabel(frame: CGRectZero)
- self.contentView.addSubview(self.titleLabel)
- self.titleLabel.textColor = UIColor.blackColor()
- self.titleLabel.font = UIFont.systemFontOfSize(14.0)
- }
- if (self.contentButton == nil)
- {
- self.contentButton = UIButton(type: .Custom)
- self.contentView.addSubview(self.contentButton)
- self.contentButton.backgroundColor = UIColor.orangeColor()
- self.contentButton.layer.cornerRadius = 5.0
- self.contentButton.layer.masksToBounds = true
- self.contentButton.titleLabel!.font = UIFont.systemFontOfSize(12.0)
- self.contentButton.setTitleColor(UIColor.redColor(),forState: .Highlighted)
- }
- if (self.statusImage == nil)
- {
- self.statusImage = UIImageView(frame: CGRectZero)
- self.contentView.addSubview(self.statusImage)
- self.statusImage.contentMode = .ScaleAspectFit
- }
- if (self.contentLabel == nil)
- {
- self.contentLabel = UILabel(frame: CGRectZero)
- self.contentView.addSubview(self.contentLabel)
- self.contentLabel.textColor = UIColor.brownColor()
- self.contentLabel.font = UIFont.systemFontOfSize(contentFont)
- self.contentLabel.numberOfLines = 0
- self.contentLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
- }
- // 设置frame
- // 标题
- self.titleLabel.frame = CGRectMake(CGFloat(originXY),CGFloat(originXY),(CGRectGetWidth(self.frame) - CGFloat(originXY) * 3 - 60.0),CGFloat(labelHeight))
- var currentView = self.titleLabel as UIView
- // 按钮
- self.contentButton.frame = CGRectMake((CGRectGetWidth(self.frame) - CGFloat(originXY) - 60.0),CGRectGetMinY(currentView.frame),60.0,CGRectGetHeight(currentView.frame))
- // 分割线
- 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))
- self.contentView.addSubview(lineH)
- lineH.backgroundColor = UIColor.lightGrayColor()
- // 状态图标
- self.statusImage.frame = CGRectMake(CGRectGetMinX(currentView.frame),(CGRectGetMinY(currentView.frame) + CGRectGetHeight(currentView.frame) + CGFloat(originXY)),CGFloat(originXY))
- currentView = self.statusImage as UIView
- // 详情
- self.contentLabel.frame = CGRectMake(CGFloat(originXY),(CGRectGetMinY(currentView.frame) + CGRectGetHeight(currentView.frame)),(width - CGFloat(originXY) * 2),0.0)
- }
- // MARK: 数据处理
- func showModel()
- {
- self.titleLabel.text = self.cellModel.title
- self.contentLabel.text = self.cellModel.content
- self.contentButton.indexPath = self.cellIndex
- let status = self.cellModel.contentStatus
- if status.boolValue
- {
- self.contentButton.setTitle("隐藏详情",forState: .Normal)
- self.contentButton.setTitleColor(UIColor.blueColor(),forState: .Normal)
- self.statusImage.image = UIImage(named: "statusDown_image")
- // 计算字生符串的宽度,高度
- var rect = self.contentLabel.frame
- let height = CustomCell.heightWithText(self.cellModel.content)
- rect.size.height = height
- self.contentLabel.frame = rect
- }
- else
- {
- self.contentButton.setTitle("显示详情",forState: .Normal)
- self.contentButton.setTitleColor(UIColor.blackColor(),forState: .Normal)
- self.statusImage.image = UIImage(named: "statusUp_image")
- // 隐藏
- var rect = self.contentLabel.frame
- rect.size.height = 0.0
- self.contentLabel.frame = rect
- }
- }
- // MARK: - 计算高度
- class func cellHeight(model:CustomModel) -> CGFloat
- {
- let status = model.contentStatus
- if status.boolValue
- {
- let height = self.heightWithText(model.content)
- return CustomCellHeightDefault + height
- }
- else
- {
- return CustomCellHeightDefault
- }
- }
- private class func heightWithText(text:String) -> CGFloat
- {
- let size:CGRect = text.boundingRectWithSize(CGSizeMake(width,999.9),options: NSStringDrawingOptions.UsesLineFragmentOrigin,attributes: [NSFontAttributeName:UIFont.systemFontOfSize(contentFont)],context: nil)
- return size.height
- }
- }
自定义headerView
- import UIKit
- let CustomHeaderHeight:CGFloat = 40.0
- let CustomHeaderIdentifier = "CustomHeader"
- let CustomHeaderWidth:CGFloat = UIScreen.mainScreen().bounds.width
- class CustomHeader: UITableViewHeaderFooterView {
- // 标题按钮
- var headerButton:UIButton!
- // 必须实现的方法
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- // 实例化
- override init(reuseIdentifier: String?)
- {
- super.init(reuseIdentifier: reuseIdentifier)
- self.setUI()
- }
- // 让单元格宽度始终为屏幕宽
- override var frame: CGRect
- {
- get
- {
- return super.frame
- }
- set (newFrame)
- {
- var frame = newFrame
- frame.size.width = CustomHeaderWidth
- super.frame = frame
- }
- }
- // 视图
- private func setUI()
- {
- if self.headerButton == nil
- {
- self.headerButton = UIButton(frame: CGRectMake(0.0,CustomHeaderWidth,CustomHeaderHeight))
- self.contentView.addSubview(self.headerButton)
- self.headerButton.backgroundColor = UIColor.greenColor()
- self.headerButton.contentHorizontalAlignment = .Center
- self.headerButton.setTitleColor(UIColor.blackColor(),forState: .Normal)
- self.headerButton.setTitleColor(UIColor.redColor(),forState: .Highlighted)
- }
- }
- }
自定义footerView
- import UIKit
- let CustomFooterHeight:CGFloat = 40.0
- let CustomFooterIdentifier = "CustomFooter"
- let CustomFooterWidth:CGFloat = UIScreen.mainScreen().bounds.width
- class CustomFooter: UITableViewHeaderFooterView {
- var label:UILabel!
- // 必须实现
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- // 实例化
- override init(reuseIdentifier: String?)
- {
- super.init(reuseIdentifier: reuseIdentifier)
- self.setUI()
- }
- // 视图
- private func setUI()
- {
- if self.label == nil
- {
- self.label = UILabel(frame: CGRectMake(0.0,CustomFooterWidth,CustomFooterHeight))
- self.contentView.addSubview(self.label)
- self.label.font = UIFont.systemFontOfSize(10.0)
- self.label.textAlignment = .Center
- self.label.backgroundColor = UIColor.yellowColor()
- }
- }
- }
自定义model