首页 > 解决方案 > UITableViewCell 背景渐变在第一次渲染时不起作用

问题描述

我有一个表格视图。我使用 xib 文件创建我的单元格。
我需要 1 个单元格(即当前用户)作为渐变背景,我创建了一个背景渐变层,但它不适合查看。在我下拉列表后,它可以工作。坏了一个

工作一

你可以看到我的截图,这是我的代码

//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

        }

这是梯度法

 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)
    }

以及如何从图层中删除渐变以供下次使用单元格?

编辑: 表视图代码

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()
    }
}

标签: iosswift

解决方案


问题是这一行:

gradient.frame = gradientLayerView.bounds

在这段代码运行的时候cellForRowAt,你的gradientLayerView还没有完全布局,所以bounds还不知道。因此,在布局确实发生后,您将gradient使用不适合其视图的 a 。frame

认为cell.setData您可以通过将调用移动到来解决问题tableView(_:willDisplay:forRowAt:),此时应该知道单元格大小。

以及如何从图层中删除渐变以供下次使用单元格?

好吧,这里的问题是您的情况别无选择:

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

问题是:如果不是怎么办?在这种情况下,如果已添加渐变层,则需要将其移除。你没有为这种情况提供任何逻辑。— 你也需要小心,因为如果已经添加了渐变层并且你的逻辑现在导致你添加另一个渐变层怎么办?基本上,您的整个方法没有考虑到关于表格视图单元格的最基本事实,即它们被重用。


推荐阅读