带阴影的分组 table 视图

Grouped table view with shadow

我想实现一个分组的 tableView 以及与下图相同的阴影。

为了存档圆角和阴影,我只是在我的主视图后面添加了一个单独的 UIView,并将它与主视图从各个方向固定在一起,就像这样

在阴影视图上应用阴影,并通过主视图上的遮罩根据单元格的索引圆角。这样就成功地实现了带阴影的蒙版圆角。

但是单元格的阴影是重叠的:

为了解决这个问题,顶部单元格应该在顶部、右侧和左侧有阴影,中间单元格只有右侧和左侧,底部单元格应该在右侧、左侧和底部有阴影。

我弄乱了这个问题很长时间,最终修改了一些 Objc 代码以获得您想要的结果。

我从来没有意愿让它也适用于单细胞。总是有一些错误。但是,对于两个或多个单元格,请在单元格本身而不是 contentView.

上使用此扩展名

内部单元格layoutSubviews

backgroundView = UIView(frame: contentView.frame)
backgroundView?.clipsToBounds = false
backgroundView?.backgroundColor = .clear

addShadowToCellInTableView(lastIndex: lastIndex, atIndexPath: indexPath)
public extension UITableViewCell {
    /** adds a drop shadow to the background view of the (grouped) cell */
    func addShadowToCellInTableView(lastIndex: Int, atIndexPath indexPath: IndexPath!) {
        let isFirstRow: Bool = indexPath.row == 0
        let isLastRow: Bool = (indexPath.row == lastIndex - 1)

        guard let backgroundView = self.backgroundView else { return }

        let backBounds = backgroundView.bounds
        // the shadow rect determines the area in which the shadow gets drawn
        var shadowRect: CGRect = backBounds.insetBy(dx: 0, dy: -10)
        if isFirstRow {
            shadowRect.origin.y += 10
        } else if isLastRow {
            shadowRect.size.height -= 10
        }

        // the mask rect ensures that the shadow doesn't bleed into other table cells
        var maskRect: CGRect = backBounds.insetBy(dx: -20, dy: 0)
        if isFirstRow {
            maskRect.origin.y -= 10
            maskRect.size.height += 10
        } else if isLastRow {
            maskRect.size.height += 10
        }

        // now configure the background view layer with the shadow
        let layer: CALayer = backgroundView.layer
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowRadius = 4
        layer.shadowOpacity = 0.23
        layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath
        layer.masksToBounds = false

        // and finally add the shadow mask
        let maskLayer = CAShapeLayer()
        maskLayer.path = UIBezierPath(rect: maskRect).cgPath
        layer.mask = maskLayer
    }

    func addShadowToSingleCell() {
        layer.shadowOpacity = 0.23
        layer.shadowRadius = 4
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowColor = UIColor.black.cgColor

        layer.shadowPath = UIBezierPath(roundedRect: contentView.frame,
                                        cornerRadius: contentView.layer.cornerRadius).cgPath
    }
}