UPDATE: Updated for Swift, Swift 2 and packaged into a drop-in replacement for UIView.

I thought drawing gradients on iOS is easy. Well, until our designer gave me this:

Smooth gradient drawn in Photoshop

I went on and implemented the drawRect: method on a custom UIView. I used CGGradient and wrote the drawing code. I ran the project in the simulator and noticed that the gradient was quite different. Ran on the device, same thing.

Gradient drawn with CGGradient

I played around with different colors and their positions but nothing turned out like the Photoshop gradient. After some head scratching I figured it must be something to do with how the colors are interpolated. CGGradient uses a linear interpolation of colors.

Plot y = x

What I need is a slope (ease-in ease-out for you familiar with animation timings) function and apply that to each color component. I actually cared only about transparency so I had to only adjust the alpha channel. I needed this:

Plot slope function

Plot slope

Looking at the documentation, CGGradient doesn’t support custom color interpolation. There is something called CGShading that does. The documentation is not absolutely clear on how to use it, but after some experimenting I came up with a solution, which is presented below. There is also a sample project available on GitHub so you can compare CGGradient and CGShading.

Hope somebody finds this useful!