Swift - 实现tableView中section分组圆角效果1(没有分区头、尾的情况)
表格分组(section)的圆角效果在许多 App 中都可以看到。其具体实现方式,根据 section 是否包含有 header 和 footer 而又有所不同。下面通过样例演示没有分区头、分区尾的情况下,如何实现圆角效果。
一、没有 header 和 footer 的情况
1,效果图
(1)tableView 中每个 section 都带有圆角,无论该分区内是只有一个单元格,还是有多个单元格。
(2)同时为了让显示效果更好,在每个单元格左右两侧还设置了边距,使其与边框保持一定的距离。
2,样例代码
(1)首先自定义一个单元格类(MyTableViewCell),并重写它的 frame 属性方法,实现边距效果。
import UIKit //自定义单元格 class MyTableViewCell: UITableViewCell { override var frame: CGRect { get { return super.frame } set { var frame = newValue frame.origin.x += 15 frame.size.width -= 2 * 15 super.frame = frame } } }
(2)主视图控制器代码如下,要实现圆角效果的关键在于 cellForRowAt 方法,根据不同情况对单元格设置不同的遮罩。
import UIKit class ViewController: UIViewController , UITableViewDelegate, UITableViewDataSource{ var tableView:UITableView? var allnames:Dictionary<Int, [String]>? override func loadView() { super.loadView() } override func viewDidLoad() { super.viewDidLoad() //初始化数据 self.allnames = [ 0:[String]([ "UILabel 标签", "UITextField 文本框", "UIButton 按钮"]), 1:[String]([ "UIDatePiker 日期选择器", "UIToolbar 工具条"]), 2:[String]([ "UIProgressView 进度条"]) ] //创建表视图 self.tableView = UITableView(frame:self.view.frame, style:.grouped) self.tableView!.delegate = self self.tableView!.dataSource = self //创建一个重用的单元格 self.tableView!.register(MyTableViewCell.self, forCellReuseIdentifier: "cell") self.view.addSubview(self.tableView!) } //返回分区 func numberOfSections(in tableView: UITableView) -> Int { return self.allnames!.count } //返回表格行数(也就是返回控件数) func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let data = self.allnames?[section] return data!.count } //创建各单元显示内容(创建参数indexPath指定的单元) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //获取单元格 let cell = self.tableView?.dequeueReusableCell(withIdentifier: "cell") as! MyTableViewCell cell.accessoryType = .disclosureIndicator //设置单元格内容 let secno = indexPath.section var data = self.allnames?[secno] cell.textLabel?.text = data![indexPath.row] //圆角半径 let cornerRadius:CGFloat = 15.0 //下面为设置圆角操作(通过遮罩实现) let sectionCount = tableView.numberOfRows(inSection: indexPath.section) let shapeLayer = CAShapeLayer() cell.layer.mask = nil //当前分区有多行数据时 if sectionCount > 1 { switch indexPath.row { //如果是第一行,左上、右上角为圆角 case 0: var bounds = cell.bounds bounds.origin.y += 1.0 //这样每一组首行顶部分割线不显示 let bezierPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: cornerRadius,height: cornerRadius)) shapeLayer.path = bezierPath.cgPath cell.layer.mask = shapeLayer //如果是最后一行,左下、右下角为圆角 case sectionCount - 1: var bounds = cell.bounds bounds.size.height -= 1.0 //这样每一组尾行底部分割线不显示 let bezierPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: cornerRadius,height: cornerRadius)) shapeLayer.path = bezierPath.cgPath cell.layer.mask = shapeLayer default: break } } //当前分区只有一行行数据时 else { //四个角都为圆角(同样设置偏移隐藏首、尾分隔线) let bezierPath = UIBezierPath(roundedRect: cell.bounds.insetBy(dx: 0.0, dy: 2.0), cornerRadius: cornerRadius) shapeLayer.path = bezierPath.cgPath cell.layer.mask = shapeLayer } return cell } } class MyTableViewCell: UITableViewCell { override var frame: CGRect { get { return super.frame } set { var frame = newValue frame.origin.x += 15 frame.size.width -= 2 * 15 super.frame = frame } } }