渐变没有填充 UITableViewCell

Posted

技术标签:

【中文标题】渐变没有填充 UITableViewCell【英文标题】:Gradient isn’t filling UITableViewCell 【发布时间】:2020-05-14 04:52:37 【问题描述】:

我编写了一个自定义 UITableView 单元格,我想为其背景使用渐变。无论我尝试什么,渐变都不会填充单元格或呈现圆角。这是渐变之前的样子 (我在这里将单元格设置为蓝色,以便您可以看到它们),这是渐变后的样子:

这是我目前所拥有的:

import UIKit
import PlaygroundSupport

class ViewController: UITableViewController 
    override func numberOfSections(in tableView: UITableView) -> Int 
        return(5)
    

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = UIView()
        view.backgroundColor = .white
        return view
    

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
        40
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        tableView.rowHeight = 200
        return 1
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath) as! CardCell
        return cell
    

    override func viewDidLoad()
        super.viewDidLoad()
        tableView.register(CardCell.self, forCellReuseIdentifier: "CardCell")
    


class CardCell: UITableViewCell 

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        layer.masksToBounds = false
        layer.shadowOpacity = 0.23
        layer.shadowRadius = 12
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowColor = UIColor.black.cgColor
        layer.cornerRadius = 6

        var colorTop = UIColor()
        colorTop = .red
        var colorBottom = UIColor()
        colorBottom = .blue

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [colorTop.cgColor, colorBottom.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
        gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
        gradientLayer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
        gradientLayer.frame = self.bounds

        contentView.layer.insertSublayer(gradientLayer, at: 0)


        contentView.layer.cornerRadius = 100

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


PlaygroundPage.current.liveView = ViewController()

【问题讨论】:

总是将图片添加到***,所以其他人不需要点击链接 在初始化时gradientLayer.frame = self.bounds 不会得到精确的单元格边界,创建一个CAGradientLayer 的属性并在layoutsubview 方法上再次设置框架 【参考方案1】:

使您的渐变层可在 Cell 范围内访问,并将其框架设置在 layoutIfNeeded 方法内:

class Cell: UITableViewCell 

    // ...

    let gradientLayer = CAGradientLayer()

    override func layoutIfNeeded() 
        super.layoutIfNeeded()

        gradientLayer.frame = bounds
    

【讨论】:

【参考方案2】:

这是你需要做的.. 将框架和圆角半径移到layoutIfNeeded

class CardCell: UITableViewCell 
    private lazy  var gradientLayer : CAGradientLayer = 
        let layer = CAGradientLayer()
        layer.colors = [UIColor.red, UIColor.blue].map$0.cgColor
        layer.startPoint = CGPoint(x: 0.5, y: 1.0)
        layer.endPoint = CGPoint(x: 0.5, y: 0.0)
        layer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
        layer.frame = self.bounds
        layer.masksToBounds = true
       return layer
    ()

    override func layoutIfNeeded() 
        super.layoutIfNeeded()
        gradientLayer.frame = bounds
        contentView.layer.cornerRadius = bounds.maxY/2
    

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        layer.masksToBounds = false
        layer.shadowOpacity = 0.9
        layer.shadowRadius = 12
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowColor = UIColor.black.cgColor
        layer.cornerRadius = 6

        contentView.layer.insertSublayer(gradientLayer, at: 0)
        contentView.layer.masksToBounds = true


    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


PlaygroundPage.current.liveView = ViewController()

结果

【讨论】:

【参考方案3】:

gradientLayer 的框架需要更新

只需覆盖 func layoutSubviews()

class CardCell: UITableViewCell 

    let gradientLayer = CAGradientLayer()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        layer.masksToBounds = false
        layer.shadowOpacity = 0.23
        layer.shadowRadius = 12
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowColor = UIColor.black.cgColor
        layer.cornerRadius = 6

        var colorTop = UIColor()
        colorTop = .red
        var colorBottom = UIColor()
        colorBottom = .blue

        gradientLayer.colors = [colorTop.cgColor, colorBottom.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
        gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
        gradientLayer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
        gradientLayer.frame = self.bounds

        contentView.layer.insertSublayer(gradientLayer, at: 0)


        contentView.layer.cornerRadius = 100

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override func layoutSubviews() 
        super.layoutSubviews()
        gradientLayer.frame = bounds
    



【讨论】:

以上是关于渐变没有填充 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

在图像中混合渐变填充角的算法

如何用线性渐变填充Android中的路径?

Qt 绘图渐变填充

如何给SVG填充和描边应用线性渐变

如何给我的 SVG 图标冠上金色的线性渐变填充(路径)颜色? [复制]

Qt 之图形(渐变填充)