iosswiftuitableviewcagradientlayerheightforrowatindexpath

UITableViewCell's layer not getting updated after heightForRowAt IndexPath


I am changing the size of each TableViewCell with:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60
}

Then, within the custom cell class, I am inserting a 'gradientLayer' as a sublayer to the Cell's layer property:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    ...
    gradientLayer.frame = self.layer.bounds
    layer.insertSublayer(gradientLayer, at: 0)
    ...
}

However, the gradient is not filling up the whole cell: enter image description here

Does anyone know why this is happening/how I can fix it?

Thank you.


Solution

  • If you use a plain UITableViewCell :

     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 100.0
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
    
            // ...
    
            let gradient =  CAGradientLayer()
            gradient.frame = cell.contentView.frame
            gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor]
            gradient.locations = [0.0, 1.0]
            cell.contentView.layer.insertSublayer(gradient, at: 0)
    
            // ...
    
            return cell
        }
    

    You need to make sure that you're adding the gradient to the contentView's layer.

    And this would work just fine.

    If you use a custom UITableViewCell class :

    Now, if you are using a custom cell class, you will need to override the layoutSubviews() method like so :

    override func layoutSubviews() {
        super.layoutSubviews()
    
        gradient.frame = contentView.frame
    }
    

    This ensures that your gradient frame is always equal to your contentView frame at anytime.

    Your custom cell class would then look like this:

    class CustomTableCell: UITableViewCell {
    
        lazy var gradient : CAGradientLayer = {
            var gradient = CAGradientLayer()
            gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor]
            gradient.locations = [0.0, 1.0]
            self.contentView.layer.insertSublayer(gradient, at: 0)
            return gradient
        }()
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
    
            // ...
    
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            // ...
    
            gradient.frame = contentView.frame
    
            // ...
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            // ...
        }
    
    
    }
    

    Just let me know if you have any additional questions !