Search code examples
iosswiftuitableviewcalayershadow

Strange UITableViewCell shadow behaviour


I am trying to add shadow to single UITableViewCell. I am using this code in my custom cell subclass:

override func layoutSubviews() {
    super.layoutSubviews()

    layer.masksToBounds = false
    layer.shadowOffset = CGSize(width: 0, height: 1)
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOpacity = 0.9
    layer.shadowRadius = 10
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
}

But the shadow usually appears only on bottom/top edge of the cell and it changes during scrolling.

This is what it does

Can anybody please help me?


Solution

  • You don't see the shadow because the cell above/below is higher in the view-hierarchy depending on whether it was dequeued before or after your custom cell. Check out the View-Hierarchy-Debugger in Xcode to spot the issue.

    You have a couple of possible solutions but I will outline 2 of them here:

    1. You can use bringSubviewToFront in your tableView to make sure your custom cell is always on top.
    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if cell.isKind(of: MyCustomShadowCell.self) {
            tableView.bringSubviewToFront(cell)
        }
    }
    
    1. Another solution would be to set the layer.zPosition of the cell to something high, so that it's always on top. Imo that's a bit hack-ish but if you wanna try: layer.zPosition = CGFloat.greatestFiniteMagnitude.