Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply Gradient to UIView in iOS 10 on a real device

I have this extension to add a Gradient to a View in Swift:

extension UIView {
    func addGradientWithColor(colorTop: UIColor, colorButton: UIColor){
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = [colorTop.cgColor, colorButton.cgColor]

        self.layer.insertSublayer(gradient, at: 0)
    }
}

Then, I use it like that in my UIViewController:

override func viewDidLoad(){
    self.view.addGradientWithColor(colorTop: UIColor.red, colorButton: UIColor.clear)        
    super.viewDidLoad()
}

I run the simulator and it works great. But when I want use my app on a real device, the Gradient does not work.

PD: I tried many ways to do a Gradient but nothing worked on a real device.

like image 309
Cristian Mora Avatar asked Jan 16 '17 16:01

Cristian Mora


Video Answer


2 Answers

The problem is that you are not resizing the layer when the size of the view changes, thus it remains at it's initial value, which mostly depends on how was the view created.

I'd recommend using an UIView subclass, and updating the layer size in the layoutSubviews method, which always gets called when the view resizes:

@IBDesignable
open class GradientView: UIView {
    @IBInspectable
    public var startColor: UIColor = .white {
        didSet {
            gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
            setNeedsDisplay()
        }
    }
    @IBInspectable
    public var endColor: UIColor = .white {
        didSet {
            gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
            setNeedsDisplay()
        }
    }

    private lazy var gradientLayer: CAGradientLayer = {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds
        gradientLayer.colors = [self.startColor.cgColor, self.endColor.cgColor]
        return gradientLayer
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.insertSublayer(gradientLayer, at: 0)
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        layer.insertSublayer(gradientLayer, at: 0)
    }

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

The code above also let's you tweak the start and end colour from Xcode so you have an estimate of how the view will look like when deployed.

like image 68
Cristik Avatar answered Sep 28 '22 00:09

Cristik


Try this, it's working for me. Code:

let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.frame.size = self.gradientView.frame.size
gradientLayer.colors = [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] //Use diffrent colors
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
self.gradientView.layer.addSublayer(gradientLayer)

For more details explanation see this: Gradient On UIView

like image 23
Jaywant Khedkar Avatar answered Sep 27 '22 22:09

Jaywant Khedkar