Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Radial gradient background in Swift

Tags:

ios

swift

I have been trying to produce a basic radial gradient background, but without success. I managed to get a linear gradient working as shown with the code below, but I have no idea how to make it radial with different colours - like in the image below. Any help would be greatly appreciated. :)

    let gradientLayer: CAGradientLayer = CAGradientLayer()     gradientLayer.colors = gradientColors     gradientLayer.locations = gradientLocations ... 

enter image description here

enter image description here

like image 625
Gugulethu Avatar asked Aug 06 '15 10:08

Gugulethu


People also ask

How do I set gradient background color in SwiftUI?

Initializing Colors SwiftUI provides with multiple ways to initialize colors. One way to do it is using Color(red: ..., green: ..., blue: ...) . You can provide the RGB (Red, Green, blue) value on a 0-1 range. You can also initialize color with UIColor (from UIKit) and NSColor (from AppKit).

What is gradient layer in Swift?

You use a gradient layer to create a color gradient containing an arbitrary number of colors. By default, the colors are spread uniformly across the layer, but you can optionally specify locations for control over the color positions through the gradient.


2 Answers

Nowadays CAGradientLayer is built-in to iOS.

It's this easy:

For years now you simply do this:

class GlowBall: UIView {     private lazy var pulse: CAGradientLayer = {         let l = CAGradientLayer()         l.type = .radial         l.colors = [ UIColor.red.cgColor,             UIColor.yellow.cgColor,             UIColor.green.cgColor,             UIColor.blue.cgColor]         l.locations = [ 0, 0.3, 0.7, 1 ]         l.startPoint = CGPoint(x: 0.5, y: 0.5)         l.endPoint = CGPoint(x: 1, y: 1)         layer.addSublayer(l)         return l     }()      override func layoutSubviews() {         super.layoutSubviews()         pulse.frame = bounds         pulse.cornerRadius = bounds.width / 2.0     }  }      

enter image description here

The key lines are:

l.colors = [ UIColor.red.cgColor,                 UIColor.yellow.cgColor,                 UIColor.green.cgColor,                 UIColor.blue.cgColor] l.locations = [ 0, 0.3, 0.7, 1 ]      

Note that you can change the "stretch" as you wish ...

l.locations = [ 0, 0.1, 0.2, 1 ]           

enter image description here

Use any colors you like

l.colors = [ UIColor.systemBlue.cgColor,                     UIColor.systemPink.cgColor,                     UIColor.systemBlue.cgColor,                     UIColor.systemPink.cgColor,                     UIColor.systemBlue.cgColor,                     UIColor.systemPink.cgColor,                     UIColor.systemBlue.cgColor,                     UIColor.systemPink.cgColor]                 l.locations = [ 0,0.1,0.2,0.3,0.4,0.5,0.6,1 ]      

enter image description here

It's really that easy now.

Very useful trick:

Say you want yellow, with a blue band at 0.6:

l.colors = [ UIColor.yellow.cgColor,                     UIColor.blue.cgColor,                     UIColor.yellow.cgColor]                 l.locations = [ 0, 0.6, 1 ]      

That works fine.

    # yellow...     # blue...     # yellow...      

But usually you do this:

    # yellow...     # yellow...     # blue...     # yellow...     # yellow...      

Notice there are TWO of the yellows at each end ...

l.colors = [ UIColor.yellow.cgColor,  UIColor.yellow.cgColor,  UIColor.blue.cgColor,  UIColor.yellow.cgColor,  UIColor.yellow.cgColor]      

In this way, you can control "how wide" the blue band is:

In this example: the blue band will be narrow and sharp:

l.locations = [ 0, 0.58, 0.6, 0.68, 1 ]      

In this example the blue band will be broad and soft:

l.locations = [ 0, 0.5, 0.6, 0.7, 1 ]      

That is really the secret to how you control gradients, and get the look you want.


How to use ...

Notice this is - very simply - a UIView !!

class GlowBall: UIView { ... 

Thus simply

  1. In storyboard, place a UIView where you want

  2. In storyboard, change the class to "GlowBall" instead of UIView

You're done!

like image 52
Fattie Avatar answered Sep 21 '22 23:09

Fattie


Here is an implementation in Swift 3 if you're just looking for a UIView radial gradient background:

class RadialGradientLayer: CALayer {      var center: CGPoint {         return CGPoint(x: bounds.width/2, y: bounds.height/2)     }      var radius: CGFloat {         return (bounds.width + bounds.height)/2     }      var colors: [UIColor] = [UIColor.black, UIColor.lightGray] {         didSet {             setNeedsDisplay()         }     }      var cgColors: [CGColor] {         return colors.map({ (color) -> CGColor in             return color.cgColor         })     }      override init() {         super.init()         needsDisplayOnBoundsChange = true     }      required init(coder aDecoder: NSCoder) {         super.init()     }      override func draw(in ctx: CGContext) {         ctx.saveGState()         let colorSpace = CGColorSpaceCreateDeviceRGB()         let locations: [CGFloat] = [0.0, 1.0]         guard let gradient = CGGradient(colorsSpace: colorSpace, colors: cgColors as CFArray, locations: locations) else {             return         }         ctx.drawRadialGradient(gradient, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: radius, options: CGGradientDrawingOptions(rawValue: 0))     }  }    class RadialGradientView: UIView {      private let gradientLayer = RadialGradientLayer()      var colors: [UIColor] {         get {             return gradientLayer.colors         }         set {             gradientLayer.colors = newValue         }     }      override func layoutSubviews() {         super.layoutSubviews()         if gradientLayer.superlayer == nil {             layer.insertSublayer(gradientLayer, at: 0)         }         gradientLayer.frame = bounds     }  } 
like image 29
Kurt J Avatar answered Sep 21 '22 23:09

Kurt J