UICollectionViewCell中的渐变BG

时间:2018-07-31 05:51:23

标签: ios swift swift4 gradient

我用信用卡一样的单元格创建了一个UICollectionView,并希望添加渐变层作为此卡的背景。首先,我添加了阴影(shadowView)的背景视图,然后添加了渐变层(bgView)的第二个视图,并添加了CAGradientLayer作为bgView的子图层。但是我没有任何渐变视图。这是我的代码:

class CardCell: BaseCell {

    private var shadowView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.white
        view.layer.shadowColor = UIColor.shadowColor.cgColor
        view.layer.shadowOffset = CGSize(width: 0, height: 1.0)
        view.layer.shadowOpacity = 0.1
        view.layer.shadowRadius = 15.0
        return view
    }()

    private var bgView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.layer.cornerRadius = 5
        view.layer.masksToBounds = true
        view.backgroundColor = .clear
        view.layer.addSublayer(createGradientLayer(for: view))
        return view
    }()

    override func setup() {
        super.setup()
        addSubview(shadowView)
        addSubview(bgView)

        // setup constraints
        shadowView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.9).isActive = true
        shadowView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1).isActive = true
        shadowView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        shadowView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

        bgView.topAnchor.constraint(equalTo: shadowView.topAnchor).isActive = true
        bgView.bottomAnchor.constraint(equalTo: shadowView.bottomAnchor).isActive = true
        bgView.leadingAnchor.constraint(equalTo: shadowView.leadingAnchor).isActive = true
        bgView.trailingAnchor.constraint(equalTo: shadowView.trailingAnchor).isActive = true

    }

    private static func createGradientLayer(for view: UIView) -> CAGradientLayer {
        let color = UIColor(red:0.95, green:0.42, blue:0.64, alpha:1.0)
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = view.bounds
        gradientLayer.colors = [color.cgColor, color.withAlphaComponent(0.7).cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 1.1, y: 1.1)
        return gradientLayer
    }

}

但是,如果我更改此代码并从bgView init中删除渐变设置并在约束后将其写入,则一切正常,但阴影视图消失了:

. . .
bgView.leadingAnchor.constraint(equalTo: shadowView.leadingAnchor).isActive = true
bgView.trailingAnchor.constraint(equalTo: shadowView.trailingAnchor).isActive = true

bgView.layoutIfNeeded()
bgView.layer.addSublayer(CardCell.createGradientLayer(for: bgView))

enter image description here

3 个答案:

答案 0 :(得分:0)

我认为在阴影视图上添加渐变层会显示阴影视图消失。您应该始终在0图层索引处添加渐变层。

bgView.layer.insertSublayer(CardCell.createGradientLayer(for: bgView), at: 0)

和您的图层创建方法,您需要使用框架而不是边界。

private static func createGradientLayer(for view: UIView) -> CAGradientLayer {
    let color = UIColor(red:0.95, green:0.42, blue:0.64, alpha:1.0)
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = view.frame
    gradientLayer.colors = [color.cgColor, color.withAlphaComponent(0.7).cgColor]
    gradientLayer.locations = nil
    return gradientLayer
}

答案 1 :(得分:0)

问题是,当您添加渐变视图时,bgView的布局并不完整。因此界限将为零。

解决方案:

private var gradient: CAGradientLayer?

override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        shadowView.layer.shadowPath = UIBezierPath(rect: shadowView.bounds).cgPath

        if let gradient = gradient {
            gradient.frame = bgView.bounds
        } else {
            gradient = TestCell.createGradientLayer(for: bgView)
            bgView.layer.addSublayer(gradient!)
        }
    }

输出:

enter image description here

答案 2 :(得分:0)

extension UIView {
func addGradientToViewWithCornerRadiusAndShadow(radius:CGFloat,firstColor:UIColor,secondColor:UIColor,locations:[CGFloat]){
        for layer in (self.layer.sublayers ?? []){
            if let layer1 = layer as? CAGradientLayer{
                layer1.removeFromSuperlayer()
            }
        }
        let gradient = CAGradientLayer()
        var rect = self.bounds
        rect.size.width = ScreenWidth
        gradient.frame = rect
        gradient.colors = [firstColor.cgColor, secondColor.cgColor]
        gradient.locations = locations as [NSNumber]
        gradient.startPoint = CGPoint.init(x: 0, y: 0)
        gradient.endPoint = CGPoint.init(x: 0, y: 1)
        gradient.cornerRadius = radius
        gradient.shadowRadius = 2
        gradient.shadowColor = UIColor.lightGray.cgColor
        gradient.shadowOffset = CGSize.init(width: 0.5, height: 0.5)
        gradient.shadowOpacity = 0.5
        self.layer.insertSublayer(gradient, at: 0)
    }
}

尝试使用此UIView扩展名。让我知道是否有帮助。