» » Gradient borders in UIKit

Gradient borders in UIKit

While playing with the gradient text in UIKit using rendered UIImage, I wanted to use the gradients for other stuff, and borders are a pretty lovely candidate.

And with the approach via UIColor, there is nothing to implement. We can assign the colors to the layer.borderColor property, and that's it.

As a reminder, below is the code to render gradient into UIImage:

import UIKit

extension UIImage {    static func gradientImage(bounds: CGRect, colors: [UIColor]) -> UIImage {        let gradientLayer = CAGradientLayer()        gradientLayer.frame = bounds        gradientLayer.colors = colors.map(\.cgColor)
        // This makes it left to right, default is top to bottom        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { ctx in            gradientLayer.render(in: ctx.cgContext)        }    }

And then you create color like this:

let gradient = UIImage.gradientImage(bounds: borderView.bounds, colors: [.systemBlue, .systemRed])
let gradientColor = UIColor(patternImage: gradient)

Last step is just a matter of assignment:

borderView.layer.borderColor = gradientColor.cgColor
borderView.layer.borderWidth = 3
CopyAnd we have a view with a gradient border.

Customizing the gradient direction

With text the most common is left to right direction created by this setting:

gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

CopyIt makes sense to tweak this to achieve different effects with these borders. Once you understand how these points work, it becomes pretty straightforward.

We basically have this coordinate space that tells the gradient layer how to render itself:

I hope my "pro" illustration helped at least a bit 😄

Or maybe a couple of examples would work better. We already saw the left to right configuration. And to create the right to left, we can flip the colors instead.

Diagonal gradient from top left to bottom right would be created using these points:

gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)

Conversely to create diagonal from bottom left to top right we would do:

gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)


Similar to the GradientLabel introduced in the previous post, we can encapsulate this configuration into UIView subclass mostly because we need to know the view's bounds for the best result.

Here is the class:

class GradientBorderView: UIView {    var gradientColors: [UIColor] = [.systemGreen, .systemMint] {        didSet {            setNeedsLayout()        }    }
    override func layoutSubviews() {        super.layoutSubviews()
        let gradient = UIImage.gradientImage(bounds: bounds, colors: gradientColors)        layer.borderColor = UIColor(patternImage: gradient).cgColor    }

Feel free to use it in your projects. You can also possibly override the init to provide default layer.borderWidth value, since the current default is 0 which won't show the border.

Related Articles

Add Your Comment

reload, if the code cannot be seen

All comments will be moderated before being published.