Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

ios - UITableViewCell background gradient not working at first render

I have a table view. I create my cells using xib files.
I need 1 cell(which is the current user) to be a gradient background, I created a background gradient layer but it does not fit to view. After I pull list down, it works. Broken one

Working one

You can see screenshots i have and this is my code

//In the table cell,
if data.userUniqueId != nil && userUIID != nil && data.userUniqueId! == userUIID! {
            let startColor = UIColor(red: 253/255.0, green: 162/255.0, blue: 75/255.0, alpha: 1)
            let endColor = UIColor(red:251/255.0, green:215/255.0, blue: 126/255.0, alpha:1)
            self.setGradient(colors: [startColor.cgColor, endColor.cgColor],angle: 90)
            self.layer.borderColor = UIColor.white.cgColor
            self.layer.borderWidth = 2
            number.textColor = UIColor.white

        }

And this is gradient method

 func setGradient(colors: [CGColor], angle: Float = 0) {
        let gradientLayerView: UIView = UIView(frame: CGRect(x:0, y: 0, width: bounds.width, height: bounds.height))
        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.frame = gradientLayerView.bounds
        gradient.colors = colors

        let alpha: Float = angle / 360
        let startPointX = powf(
            sinf(2 * Float.pi * ((alpha + 0.75) / 2)),
            2
        )
        let startPointY = powf(
            sinf(2 * Float.pi * ((alpha + 0) / 2)),
            2
        )
        let endPointX = powf(
            sinf(2 * Float.pi * ((alpha + 0.25) / 2)),
            2
        )
        let endPointY = powf(
            sinf(2 * Float.pi * ((alpha + 0.5) / 2)),
            2
        )

        gradient.endPoint = CGPoint(x: CGFloat(endPointX),y: CGFloat(endPointY))
        gradient.startPoint = CGPoint(x: CGFloat(startPointX), y: CGFloat(startPointY))

        gradientLayerView.layer.insertSublayer(gradient, at: 0)
        layer.insertSublayer(gradientLayerView.layer, at: 0)
    }

And also how can I remove gradient from layer for next usage of cells?

EDIT: Table View Codes

extension RecordsViewController : UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return values.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "ScoreBoardCell", for: indexPath) as? ScoreBoardCell {
            let score = self.values[indexPath.row]
            cell.setData(indexPath.row, score)
            cell.selectionStyle = .none
            return cell
        }
        return UITableViewCell()
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is this line:

gradient.frame = gradientLayerView.bounds

At the time this code runs in cellForRowAt, your gradientLayerView has not yet been fully laid out, so its bounds are not yet known. Thus, you are saddling your gradient with a frame which will not fit its view after layout does take place.

I think you can solve the problem by moving the call to cell.setData to tableView(_:willDisplay:forRowAt:), at which point the cell size should be known.

And also how can I remove gradient from layer for next usage of cells?

Well, the problem here is that your condition has no alternative:

if data.userUniqueId != nil && userUIID != nil && data.userUniqueId! == userUIID!

The question is: what if not? In that case, if the gradient layer has been added, it needs to be removed. You have provided no logic for that situation. — Also you need to be careful because what if the gradient layer has been added and your logic now causes you to add another gradient layer? Basically your whole approach fails to take account of the most fundamental fact about table view cells, namely that they are reused.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...