Why gradient doesn't cover the whole width of the view

The problem is likely that you are adding the gradient layer in viewDidLoad(). A view doesn't get set to it's final size until after viewDidLoad().

Your view controller may be set up in your XIB/Storyboard for a different screen-size than you're running it on. (Say you have it set to iPhone SE size, but you're running it on a 6. The 6's screen is a little wider, so the layer will get set to the width of the iPhone SE, when the view is first loaded. Then the view will be resized, but the layer's size will never be adjusted.)

You should implement the UIViewController method viewDidLayoutSubviews(), and in that method, adjust the layer's frame:

override func viewDidLayoutSubviews() {
  gradientLayer.frame = self.view.bounds
}

That way if the view gets resized (due to auto-rotation, for example) the gradient layer will be automatically adjusted accordingly.

EDIT:

As pointed out by Sulthan, changes to a layer's frame are animated by default. You should probably wrap the frame change in a CATransaction.begin/CATransaction.end and disable actions, like below:

override func viewDidLayoutSubviews() {
  CATransaction.begin()
  CATransaction.setDisableActions(true)
  gradientLayer.frame = self.view.bounds
  CATransaction.commit()
}

Tags:

Ios

Swift