How can I add my gradient layer as a sub-layer to my view with the same size, which I want to use in other classes?
I tried to do it with "self.bounds" but it didn't work. If I give it strict dimensions, for example: gradientLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100) - it will work, but I need the same size as my view.
final class ShimmerLabel: UIView {
private lazy var backShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = UIColor(red: 65/255, green: 65/255, blue: 65/255, alpha: 1)
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
private lazy var frontShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = .white
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
init() {
super.init(frame: .zero)
configureGradientLayer()
configureLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureGradientLayer() {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0, 1]
gradientLayer.frame = bounds // Dont work with bounds :((
layer.addSublayer(gradientLayer)
}
private func configureLayout() {
addSubview(backShimmerTextLabel)
backShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
addSubview(frontShimmerTextLabel)
frontShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
}
}
You can use the "base" layer of a view as a CAGradientLayer
like this:
// use the "base" layer as a gradient layer
lazy var gradientLayer: CAGradientLayer = self.layer as! CAGradientLayer
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
So your class becomes:
final class ShimmerLabel: UIView {
private lazy var backShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = UIColor(red: 65/255, green: 65/255, blue: 65/255, alpha: 1)
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
private lazy var frontShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = .white
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
// use the "base" layer as a gradient layer
lazy var gradientLayer: CAGradientLayer = self.layer as! CAGradientLayer
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
init() {
super.init(frame: .zero)
configureGradientLayer()
configureLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureGradientLayer() {
gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0, 1]
}
private func configureLayout() {
addSubview(backShimmerTextLabel)
backShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
addSubview(frontShimmerTextLabel)
frontShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
}
}
and the gradient will always fill the view frame. No need to add sublayer(s).
Edit
If you need the gradient layer to be a sublayer, you need to update its frame in layoutSubviews()
:
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
}
So, make let gradientLayer = CAGradientLayer()
a property of your view...
final class ShimmerLabel: UIView {
private let gradientLayer: CAGradientLayer = CAGradientLayer()
private lazy var backShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = UIColor(red: 65/255, green: 65/255, blue: 65/255, alpha: 1)
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
private lazy var frontShimmerTextLabel: UILabel = {
let label = UILabel()
label.text = "Shimmer"
label.textColor = .white
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
return label
}()
init() {
super.init(frame: .zero)
configureGradientLayer()
configureLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureGradientLayer() {
gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0, 1]
layer.addSublayer(gradientLayer)
}
private func configureLayout() {
addSubview(backShimmerTextLabel)
backShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
addSubview(frontShimmerTextLabel)
frontShimmerTextLabel.snp.makeConstraints { make in
make.width.height.equalToSuperview()
}
}
override func layoutSubviews() {
super.layoutSubviews()
// update gradient layer frame
gradientLayer.frame = bounds
}
}