Q:

CAGradientLayer not applying to the full view in programmatically created UI

I'm working on an iOS project that's creating all its UIs programmatically. Not storyboards.
I want to add a gradient to the background of a UIViewController's UIView.
I created the following extension method.
extension UIView {
    
    func addGradient(colors: [UIColor]) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.bounds = bounds
        gradientLayer.colors = colors.map { $0.cgColor }
        layer.insertSublayer(gradientLayer, at: 0)
    }
    
}

And I added the gradient in the viewDidLoad of the ViewController like so.
let topColor = UIColor(red: 0.28, green: 0.521, blue: 0.696, alpha: 1)
let bottomColor = UIColor(red: 0.575, green: 0.615, blue: 0.692, alpha: 1)
view.addGradient(colors: [topColor, bottomColor])

But the gradient is not being applied to the full width and height of the screen.

I printed out the bounds of the view and it shows these values.

(0.0, 0.0, 375.0, 812.0)

So I'm not sure why the gradient is still not covering the full view.

A:

In addGradient(colors:) method set the gradientLayer's frame instead of bounds, i.e.
func addGradient(colors: [UIColor]) {
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = bounds //here.....

    //rest of the code...
}

Also, as suggested move your code to viewDidLayoutSubviews() method,
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let topColor = UIColor(red: 0.28, green: 0.521, blue: 0.696, alpha: 1)
    let bottomColor = UIColor(red: 0.575, green: 0.615, blue: 0.692, alpha: 1)
    view.addGradient(colors: [topColor, bottomColor])
}

This is because, the gradient's frame must change everytime there are any changes in the view's layout. Example, in portrait and landscape orientations.

