gradient keeps switching between cells in collection view in swift

孤街浪徒 提交于 2019-12-01 13:17:41

问题


I have a gradient background for my collection view cell and each gradient is different depending on what tag the cell is (e.g Christmas is a purple gradient, birthday is a green gradient) however when scrolling through the collection view, the gradients keep on changing cells. is there a way to fix this from happening?

this is the code I use to set the gradient to the background view. it is in cellForItemAt

cell.mainView.setGradientBackground(colours: self.getColourFromTag(tag: self.lists[indexPath.item].tag))

.setGradientBackground is an extension of UIView which just sets a gradient to the background. shown here:

func setGradientBackground(colours: [CGColor]) {

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = bounds
    gradientLayer.colors = colours
    gradientLayer.locations = [0.0, 1.0]
    gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
    gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
    layer.insertSublayer(gradientLayer, at: 0)
}

I use the method below to get what colours are in the gradient

func getColourFromTag(tag: String) -> [CGColor] {

    if tag == "Christmas" {

        return [Colours.gradients.festive.start.cgColor, Colours.gradients.festive.end.cgColor]

    }else if tag == "Birthday" {

        return [Colours.gradients.lime.start.cgColor, Colours.gradients.lime.end.cgColor]

    }else if tag == "Valentines Day" {

        return [Colours.gradients.strawberry.start.cgColor, Colours.gradients.strawberry.end.cgColor]

    }else if tag == "Charity" {

        return [Colours.gradients.blueberry.start.cgColor, Colours.gradients.blueberry.end.cgColor]

    }else if tag == "Event" {

        return [Colours.gradients.fire.start.cgColor, Colours.gradients.fire.end.cgColor]

    }else{
        return [Colours.gradients.midnight.start.cgColor, Colours.gradients.midnight.end.cgColor]
    }
}

I have tried appending each [colour] into an array, then placing that into the .setGradientBackground at the indexPath.item like so:

var colours = [[CGColor]]()

colours[indexPath.item] = self.getColourFromTag(tag: self.lists[indexPath.item].tag)
cell.mainView.setGradientBackground(colours: colours[indexPath.item])

however, this does not work since it is out of range. Does anyone have a solution? thank you.


回答1:


Reading your code in setGradientBackground(), you always init a new CAGradientLayer and insert it at the lowest position in your cell. Every time setGradientBackground() gets called again, the new gradient layer will be positioned below all other gradients you already inserted.

Try to get a already existing CAGradientLayer from sublayers and set the new colors.

    var gradientLayer = CAGradientLayer()
    if let sublayers = layer.sublayers {
        for sublayer in sublayers {
            if let gLayer = sublayer as? CAGradientLayer {
                gradientLayer = gLayer
                break
            }
        }
    }
    gradientLayer.frame = bounds
    gradientLayer.colors = colours
    gradientLayer.locations = [0.0, 1.0]
    gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
    gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
    layer.insertSublayer(gradientLayer, at: 0)

EDIT

This is a more swift like version (Swift 4.2) using compactMap() for getting the first existing gradient layer in layer.sublayers:

if let existingLayer = (layer.sublayers?.compactMap { $0 as? CAGradientLayer })?.first {
    gradientLayer = existingLayer
}


来源:https://stackoverflow.com/questions/53596784/gradient-keeps-switching-between-cells-in-collection-view-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!