Home iOS & Swift Books iOS Animations by Tutorials

16
Gradient Animations Written by Marin Todorov

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

A lot of the look and feel of iOS comes from very subtle animations in the UI.

While it is no longer a part of iOS, one of the nicest was a simple little animation: the “slide to unlock” label on the lock screen.

In this chapter you’ll learn how to mimic this effect with a moving gradient and how to animate the colors and layout of those gradients:

You’ll animate the gradient for a “Slide to reveal” label and then reveal a cool mystery effect when the user swipes over the label. You’ll have to work through this chapter, however, to see what this cool effect is!

As an extra bonus, you’ll learn how to create a layer mask out of a piece of text and use it to mask a gradient.

Drawing Your First Gradient

Open the starter project for this chapter and select Main.storyboard to see how the UI looks at present:

There’s a static label on top that mimics the iPhone clock on the lock screen and another view near the bottom.

The bottom view is an instance of AnimatedMaskLabel that’s included with the starter project. You’ll work with this class throughout this chapter to add gradient animations.

Build and run your project; you’ll see just the faux clock appear at the top of the screen:

You’ll first draw the base gradient of AnimatedMaskLabel. Add the following code to AnimatedMaskLabel.swift inside the gradientLayer property code after the comment shown below:

// Configure the gradient here
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

This defines the orientation of the gradient and its start and end points.

Now add the following code to define the colors that build up the gradient after the code you just added:

let colors = [
  UIColor.black.cgColor,
  UIColor.white.cgColor,
  UIColor.black.cgColor
]
gradientLayer.colors = colors

The gradient above starts with a black color, blends to white, and finally blends back to black.

You can also specify where exactly in the gradient’s frame these colors should appear. Add the following code below:

let locations: [NSNumber] = [
  0.25,
  0.5,
  0.75
]
gradientLayer.locations = locations

This sets up the gradient color milestones as follows:

You can have as many key points and color milestones as you like, but the text gradient animation in this chapter only needs the simple black-white-black gradient shown above.

Add the following code to layoutSubviews() to give the gradient a frame:

gradientLayer.frame = bounds

All that you need to do now is add the gradient to the view’s layer to see it in action. Add the line of code below to the end of didMoveToWindow():

layer.addSublayer(gradientLayer)

Build and run your project; you should see the app display the exact gradient you’re looking for:

That’s a great start! Now you need to figure out how to animate this gradient.

Animating Gradients

CAGradientLayer offers you four animatable properties along with the ones inherited from CALayer:

let gradientAnimation = CABasicAnimation(keyPath: "locations")
gradientAnimation.fromValue = [0.0, 0.0, 0.25]
gradientAnimation.toValue = [0.75, 1.0, 1.0]
gradientAnimation.duration = 3.0
gradientAnimation.repeatCount = Float.infinity

gradientLayer.add(gradientAnimation, forKey: nil)

gradientLayer.frame = CGRect(  
  x: -bounds.size.width,     
  y: bounds.origin.y,   
  width: 3 * bounds.size.width,     
  height: bounds.size.height)

Creating a Text Mask

In this section you’ll render the string stored in the text property of AnimatedMaskLabel and use that to mask the gradient layer. Create a new constant property inside the AnimatedMaskLabel class to hold the text attributes as follows:

let textAttributes: [NSAttributedString.Key: Any] = {
  let style = NSMutableParagraphStyle()
  style.alignment = .center
  return [
    .font: UIFont.systemFont(
      ofSize: 28, 
      weight: .thin),
    .paragraphStyle: style
  ]
}()
let image = UIGraphicsImageRenderer(size: bounds.size)
  .image { _ in
    text.draw(in: bounds, withAttributes: textAttributes)
}
let maskLayer = CALayer()
maskLayer.backgroundColor = UIColor.clear.cgColor
maskLayer.frame = bounds.offsetBy(dx: bounds.size.width, dy: 0)
maskLayer.contents = image.cgImage
gradientLayer.mask = maskLayer

Key Points

  • You can draw gradients on screen by using the CAGradientLayer and setting the gradient colors.
  • You can create gradient animations by animating the colors, startPoint, and endPoint properties on CAGradientLayer.
  • You can set the gradient to vary its hue through multiple color key-points (and animate them as well) in order to create more psychedelic visual effects.

Challenges

I know the suspense is killing you; these two challenges will add a slide gesture recognizer to the label and add one additional color effect to the gradient animation.

Challenge 1: Slide to Reveal Gesture Recognizer

Open ViewController.swift and add the following code to viewDidLoad():

let swipe = UISwipeGestureRecognizer(
  target: self,
  action: #selector(ViewController.didSlide))
swipe.direction = .right
slideView.addGestureRecognizer(swipe)

Challenge 2: Psychedelic Gradient Animations

In the final challenge of this chapter you’ll experiment with adding more colors to the gradient and observe the effects.

UIColor.yellow
UIColor.green
UIColor.orange
UIColor.cyan
UIColor.red
UIColor.yellow

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

© 2022 Razeware LLC

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.