Search code examples
iosswiftuitableviewcagradientlayer

Gradient in UIView inside UITableViewCell changed after scroll


I have set a gradient color to UIView inside my UITableViewCell. Everything works fine in the first load but after scroll, the gradient color is loaded again and change the position every time than the actual set condition. Here's my code for implementing gradient color :

what should I do?

Add Gradient Layer

func gradient(frame:CGRect,colors: [CGColor]) -> CAGradientLayer {
    let layer = CAGradientLayer()
    layer.frame = frame
    layer.startPoint = CGPoint(x: 1.0, y: 0.0)
    layer.endPoint = CGPoint(x: 0.0, y: 1.0)
    layer.locations = [0.5,0.35]
    layer.colors = colors
    return layer
}

UITableViewCell Class

class AllOfferlistCell: UITableViewCell {

    @IBOutlet weak var lbltitle: UILabel!
    @IBOutlet weak var lblPopular: UILabel!
    @IBOutlet weak var VwPercentage: UIView!   
}

tableView cellForRowAtindexPath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AllOfferlistCell

    cell.lbltitle.text = "Index \(indexPath.row)"

    if self.DataArray[indexPath.row].Flag == "1"{

        cell.VwPercentage.layer.insertSublayer(gradient(frame: cell.VwPercentage.bounds, colors: [UIColor.red.cgColor,UIColor.white.cgColor]), at: 1)
        cell.lblPopular.text = "POPULAR"

    }else{

        cell.VwPercentage.layer.insertSublayer(gradient(frame: cell.VwPercentage.bounds, colors: [UIColor.blue.cgColor,UIColor.white.cgColor]), at: 1)
        cell.lblPopular.text = "50% OFF"
    }

    return cell
}

Output :

First time load

enter image description here

After scrolling

enter image description here


Solution

  • Create custom view like below

    @IBDesignable class TriangleGradientView: UIView {
        @IBInspectable var topColor: UIColor = UIColor.red {
            didSet {
                setGradient()
            }
        }
        @IBInspectable var bottomColor: UIColor = UIColor.blue {
            didSet {
                setGradient()
            }
        }
        
        override class var layerClass: AnyClass {
            return CAGradientLayer.self
        }
        
        override func layoutSubviews() {
            super.layoutSubviews()
            setGradient()
        }
        
        private func setGradient() {
            (layer as! CAGradientLayer).colors = [topColor.cgColor, bottomColor.cgColor]
            (layer as! CAGradientLayer).startPoint = CGPoint(x: 1.0, y: 0.0)
            (layer as! CAGradientLayer).endPoint = CGPoint(x: 0.0, y: 1.0)
            (layer as! CAGradientLayer).locations = [0.5,0.35]
        }
    
    }
    

    Use

    1. set customclass of VwPercentage to TriangleGradientView in interface builder

    2. change VwPercentage type to TriangleGradientView.

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AllOfferlistCell
          cell.lbltitle.text = "Index \(indexPath.row)"
          if self.DataArray[indexPath.row].Flag == "1"{
              cell.VwPercentage.topColor = .red
              cell.lblPopular.text = "POPULAR"
          }else{
              cell.VwPercentage.topColor = .blue
              cell.lblPopular.text = "50% OFF"
          }
          cell.VwPercentage.bottomColor = .white
          return cell
      }