Reputation: 2034
I'm trying to add Horizontal Gradient to UIView by following way
extension UIView {
func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) {
let gradient = CAGradientLayer()
gradient.colors = [color1.cgColor, color2.cgColor]
gradient.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
gradient.frame = bounds
layer.insertSublayer(gradient, at: 0)
}
}
if let color1 = UIColor(hexString: "364190"), let color2 = UIColor(hexString: "699cf5"){
self.statusBarView.insertHorizontalGradient(color1, color2)
}
if let color1 = UIColor(hexString: "182395"), let color2 = UIColor(hexString: "5497f0"){
self.navigationBarView.insertHorizontalGradient(color1, color2)
}
But on iPhone 6Plus its not getting applied to whole UIView. But on iPhone 6 its perfect.
Upvotes: 1
Views: 2371
Reputation: 130200
You have to update the gradient everytime the frame of the view changes. Using an extension for it is not the best solution because you would have to override UIView.layoutSubviews
in all UIView
instances that use it. Instead, you could wrap the layer into a view:
@IBDesignable
public class GradientView: UIView {
private func createGradient() -> CAGradientLayer {
let gradient = CAGradientLayer()
gradient.transform = CATransform3DMakeRotation(.pi / 2, 0, 0, 1)
gradient.frame = bounds
layer.insertSublayer(gradient, at: 0)
return gradient
}
private var gradient: CAGradientLayer?
@IBInspectable
public var color1: UIColor? {
didSet {
updateColors()
}
}
@IBInspectable
public var color2: UIColor? {
didSet {
updateColors()
}
}
required public init?(coder: NSCoder) {
super.init(coder: coder)
gradient = createGradient()
updateColors()
}
override public init(frame: CGRect) {
super.init(frame: frame)
gradient = createGradient()
updateColors()
}
override public func layoutSubviews() {
super.layoutSubviews()
gradient?.frame = bounds
}
private func updateColors() {
guard
let color1 = color1,
let color2 = color2
else {
return
}
gradient?.colors = [color1.cgColor, color2.cgColor]
}
}
and then:
extension UIView {
func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) -> GradientView {
let gradientView = GradientView(frame: bounds)
gradientView.color1 = color1
gradientView.color2 = color2
gradientView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.insertSubview(gradientView, at 0)
return gradientView
}
}
Note that I have made the view @IBDesignable
, with both colors @IBInspectable
, therefore you can actually preview the gradient in your storyboards/xibs.
Upvotes: 5
Reputation: 100549
You have to call it inside viewDidLayoutSubviews
as it contains the correct frame not in viewDidLoad
, also make sure that this function is called multiple times , so either wrap the code inside once bool , or set only the frame of the gradient inside it
Upvotes: 1
Reputation: 14379
Instead gradient.frame = bounds
try
gradient.frame = CGRect(x: bounds.origin.x , y: bounds.origin.y, width: UIScreen.main.bounds.width , height: bounds.height)
as your view covering full width
& this prevents viewDidLayoutSubviews
multiple calls
Upvotes: 1