Swift: gradient on a cell of a tableview

2019-03-04 09:21发布

问题:

On tableView's cells, I'm trying to define a gradient with the following Swift code:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell:UITableViewCell = self.tableView?.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
    cell.backgroundColor=UIColor.clearColor()
    let gradient : CAGradientLayer = CAGradientLayer()
    var arrayColors:Array<AnyObject> = [UIColor.blackColor().CGColor, UIColor.whiteColor().CGColor]
    gradient.colors=arrayColors
    gradient.frame = cell.bounds
    cell.layer.insertSublayer(gradient, atIndex: UInt32(indexPath.row))

    return cell
 }

The behavior is very chaotic: when the view is first loaded, all cells have a white background. And if I scroll up and down, some content's cells disappear (title and subtitle) and the gradient finally appears in these cells (randomly, some other cells stay with a white background). Is it related to this cast -> UInt32(indexPath.row) ?

回答1:

The gradient is a visual ornamentation. It is specific to the cell class. How the cell looks is the responsibility of the cell. It should be defined in the cell class then. It absolutely does not belong to the cellForRowAtIndexPath which should be solely about choosing the right cell for the right row. But you are configuring the internals of the cell in that method and this, combined with the way how queueing works, causes all the issues.

1) Create a subclass of UITableViewCell (programatically, IB..it doesn't really matter)

2) Add the layer in awakeFromNib or layoutSubviews to the backroundView property.

3) register the cell in viewDidLoad in your tableViewController.



回答2:

I had a similar problem, my mistake was inserting the new layer with gradient directly in the cell, try inserting the new layer to the backgroundView something like this

let gradient = CAGradientLayer()
// layer setup...
cell.backgroundView = UIView()
cell.backgroundView?.layer.insertSublayer(gradientLayer, atIndex: 0)

Hope this helps.