I messed around with this for ages, and eventually altered some Objc code to have your desired result.
I never had the will to make it work for single cells too. Always a few bugs. However for two or more cells, use this extension on the cell itself and not the contentView
.
Inside cells 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
}
}