Making Gradient Background in Swift - the Right Way

How to Apply Gradient to background view of iOS Swift App

The Colors you're providing to gradient must be of type CGColor. So set your array of CGColor to gl.colors.

The correct code is :

class Colors {
var gl:CAGradientLayer!

init() {
let colorTop = UIColor(red: 192.0 / 255.0, green: 38.0 / 255.0, blue: 42.0 / 255.0, alpha: 1.0).cgColor
let colorBottom = UIColor(red: 35.0 / 255.0, green: 2.0 / 255.0, blue: 2.0 / 255.0, alpha: 1.0).cgColor

self.gl = CAGradientLayer()
self.gl.colors = [colorTop, colorBottom]
self.gl.locations = [0.0, 1.0]
}
}

Programmatically create a UIView with color gradient

Objective-C:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
CAGradientLayer *gradient = [CAGradientLayer layer];

gradient.frame = view.bounds;
gradient.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor];

[view.layer insertSublayer:gradient atIndex:0];

Swift:

let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))
let gradient = CAGradientLayer()

gradient.frame = view.bounds
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]

view.layer.insertSublayer(gradient, at: 0)

Info: use startPoint and endPoint to change direction of gradient.

If there are any other views added onto this UIView (such as a UILabel), you may want to consider setting the background color of those UIView’s to [UIColor clearColor] so the gradient view is presented instead of the background color for sub views. Using clearColor has a slight performance hit.

background Gradient : linear left to right in objective C

You need to set the startPoint and endPoint property of your gradientLayer. They represent the start coordinates of your first color and the coordinates of the end of your last color.

They are both CGPoints and their x and y should have values between 0.0 et 1.0.

By default the startPoint has these coordinates (0.5, 0.0), while the endPoint has those (0.5, 1.0).

(0.0, 0.0) is the top left corner while (1.0, 1.0) is the bottom right corner

so try:

theViewGradient.startPoint = CGPointMake(0.0, 0.5);
theViewGradient.endPoint = CGPointMake(1.0, 0.5);

Swift: Background gradient for UIView

There were 2 problems:

  • I needed to set the start and end points to provide a gradient direction:

    func setGradientBackground(colorTop: UIColor, colorBottom: UIColor) {
    let gradientLayer = CAGradientLayer()
    gradientLayer.colors = [colorBottom.cgColor, colorTop.cgColor]
    gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
    gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
    gradientLayer.locations = [0, 1]
    gradientLayer.frame = bounds

    layer.insertSublayer(gradientLayer, at: 0)
    }
  • And the second issue was that CAGradientLayer takes effect after the view is layed out. I solved that calling setGradientBackground() on viewDidAppear:

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    separatorView.setGradientBackground(colorTop: .clear, colorBottom: Colors.darkGrey)
    }

Is there a way to make gradient background color in the interface builder?

To draw a gradient, you will have to subclass and override the drawRect programmatically:

- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSaveGState(context);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents
(colorSpace,
(const CGFloat[8]){1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f},
(const CGFloat[2]){0.0f,1.0f},
2);

CGContextDrawLinearGradient(context,
gradient,
CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMinY(self.bounds)),
CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)),
0);

CGColorSpaceRelease(colorSpace);
CGContextRestoreGState(context);
}

The easiest way, which keeps your cells in the interface builder, is probably to subclass a UIView to have it draw a gradient in its drawRect and place it in your cell behind the other subviews:

GradientView *gradientView = [[GradientView alloc] init];
gradientView.frame = cell.bounds;
[cell addSubview:gradientView];
[cell sendSubviewToBack:gradientView];

However, the best way to do it is probably not to use the interface builder for this and make a subclass of UITableViewCell. For advanced customization, interface builders tend to only make things more complicated in my experience. That's up to personal preference though.

Set Background Gradient on Button in Swift

Your code works fine. You just have to remember to set the gradient's frame every time. It is better to just make the gradient category also set the frame of the view for you.

That way you don't forget and it applies fine.

import UIKit

extension UIView {

func applyGradient(colours: [UIColor]) -> CAGradientLayer {
return self.applyGradient(colours: colours, locations: nil)
}

func applyGradient(colours: [UIColor], locations: [NSNumber]?) -> CAGradientLayer {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colours.map { $0.cgColor }
gradient.locations = locations
self.layer.insertSublayer(gradient, at: 0)
return gradient
}
}

class ViewController: UIViewController {

@IBOutlet weak var btn: UIButton!

override func viewDidLoad() {
super.viewDidLoad()

self.btn.applyGradient(colours: [.yellow, .blue])
self.view.applyGradient(colours: [.yellow, .blue, .red], locations: [0.0, 0.5, 1.0])
}

}

Buttons are views. You apply gradients to it the same way you would apply it to any other view.

Picture Proof:
Sample Image

Video Proof:
https://i.imgur.com/ssDTqPu.mp4

Applying gradient background for UIView using auto layout

You can subclass the UIView and override drawRect method where you add your gradient.

Updated to Swift 4


class GradientView: UIView {

private let gradient : CAGradientLayer = CAGradientLayer()
private let gradientStartColor: UIColor
private let gradientEndColor: UIColor

init(gradientStartColor: UIColor, gradientEndColor: UIColor) {
self.gradientStartColor = gradientStartColor
self.gradientEndColor = gradientEndColor
super.init(frame: .zero)
}

required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }

override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = self.bounds
}

override public func draw(_ rect: CGRect) {
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.cgColor, gradientStartColor.cgColor]
gradient.startPoint = CGPoint(x: 1, y: 0)
gradient.endPoint = CGPoint(x: 0.2, y: 1)
if gradient.superlayer == nil {
layer.insertSublayer(gradient, at: 0)
}
}
}

After you create your UIView you just need to add your constraints to that view.



Related Topics



Leave a reply



Submit