I try to make a standard gradient top-bottom with long UIView. But it's not full. The nib is part of UITableViewCell, so I don't have access to viewDidLayoutSubviews()
as in this thread.
I've tried to call contentView.layoutIfNeeded()
from the code version of this view. I called it when UITableView cellForRowAtIndexPath
gets called. But it's no effect.
I prepare the gradient in 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)
Is there something wrong with my code?
You should use view's bounds
instead of frame
, because your layer is inside of the view, and the frame may have an offset.
The layout of the view is changed after awakeFromNib
. So you should resize the layer in layoutSubviews
of the view. For this create a property gradient
and:
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
}
EDIT: An alternative is a custom view with own layer class:
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 ]
if let gradient = self.layer as? CAGradientLayer {
gradient.colors = colors
}
}
}
This is more elegant, because you can replace the static colors with IB inspectables, and you have a reusable component view.
override func layoutSubviews() {
super.layoutSubviews()
if let gradient = baseView.layer.sublayers?[0] as? CAGradientLayer {
gradient.frame = self.bounds
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With