简体   繁体   中英

gradient keeps switching between cells in collection view in swift

I have a gradient background for my collection view cell and each gradient is different depending on what tag the cell is (eg 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.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM