为什么UITableViewCell中的渐变层不能覆盖整个帧?

时间:2017-12-22 07:14:39

标签: ios swift uitableview uiview cagradientlayer

我尝试使用长UIView制作标准渐变上下。但它并不完整。 nib是UITableViewCell的一部分,因此我无权访问this thread中的viewDidLayoutSubviews()

enter image description here

我试图从此视图的代码版本中调用contentView.layoutIfNeeded()。我调用UITableView cellForRowAtIndexPath时调用它。但它没有效果。

我在awakeFromNib()准备渐变。

let colors = [
            UIColor(red: 33/255.0, green: 33/255.0, blue: 33/255.0, alpha: 1.0).cgColor,
            UIColor(red: 51/255.0, green: 51/255.0, blue: 51/255.0, alpha: 1.0).cgColor]
let gradient = CAGradientLayer()
gradient.frame = gradientView.bounds
gradient.colors = colors
gradientView.layer.insertSublayer(gradient, at: 0) 

我的代码有问题吗?

2 个答案:

答案 0 :(得分:6)

您应该使用视图bounds而不是frame,因为您的图层位于视图内部,并且框架可能有偏移。

awakeFromNib之后视图的布局会发生变化。因此,您应该在视图的layoutSubviews中调整图层大小。为此,创建一个属性gradient和:

let gradient: CAGradientLayer = CAGradientLayer()

override func awakeFromNib() {
    ...
    let colors = [
                UIColor(red: 33/255.0, green: 33/255.0, blue: 33/255.0, alpha: 1.0).cgColor,
                UIColor(red: 51/255.0, green: 51/255.0, blue: 51/255.0, alpha: 1.0).cgColor]
    gradient.frame = bounds
    gradient.colors = colors
    gradientView.layer.insertSublayer(gradient, at: 0) 
    ...
}

override func layoutSubviews() {
    super.layoutSubviews()
    gradient.frame = bounds
}

编辑:另一种选择是具有自己的图层类的自定义视图:

public class GradientLayer: UIView {
    @IBInspectable var startColor: UIColor! = UIColor(red: 33/255.0, green: 33/255.0, blue: 33/255.0, alpha: 1.0)
    @IBInspectable var endColor: UIColor! = UIColor(red: 51/255.0, green: 51/255.0, blue: 51/255.0, alpha: 1.0)

    override class var layerClass : AnyClass {
        return CAGradientLayer.self}
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        let colors = [ startColor.cgColor, endColor.cgColor ]
        let gradient as self.layer as CAGradientLayer

        gradient.colors = colors
    }
}

这更优雅,因为你可以用 IB inspectables 替换静态颜色,并且你有一个可重用的组件视图。

答案 1 :(得分:2)

 override func layoutSubviews() {
        super.layoutSubviews()

        if let gradient = baseView.layer.sublayers?[0] as? CAGradientLayer {
            gradient.frame = self.bounds
        }
 }