当前位置: > > > Swift - 实现tableView中section分组圆角效果1(没有分区头、尾的情况)

Swift - 实现tableView中section分组圆角效果1(没有分区头、尾的情况)

    表格分组(section)的圆角效果在许多 App 中都可以看到。其具体实现方式,根据 section 是否包含有 headerfooter 而又有所不同。下面通过样例演示没有分区头、分区尾的情况下,如何实现圆角效果。

一、没有 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
        }
    }
}
评论0