Animations and CGGeometry in iOS

Animations are awesome and having a sense of playfulness really makes an app come to life and feel special. The iOS framework makes it simple to chain together simple tools provided by the iOS framework to create delightful animations. For a project I am working on, I wanted to design a moving star backdrop that created the feeling of being in outer space staring out from a fixed point and slowly moving up.

Amazingly the only two concepts needed to complete this animation are UIView animations and object frame properties (and a little bit of elbow grease in tweaking all of the timing and sizing until it looks right).

UIView Animations

UIView animateWithDuration

The UIView class is a robust class that at its simplest defines and encapsulates areas on the screen and provides the interface for managing the content in that area. A lot of classes that we work with inherit from UIView including UITableViewCell, UILabel, and UIImageView. Due to this inheritance, using any of the subclasses comes with the full functionality of UIView including the animateWithDuration: family of class methods.

animateWithDuration: lets you take a property of a UIView and, as the name implies, animate it over a duration to another state. You can animate a variety of properties such as location, size, rotation, alpha transparency, etc. Keep in mind that this animation is only from one state to another state and would not be appropriate for animations with multiple states (you might consider keyframe animations for that use case).

For example, to create a moving star animation you could animate a star object to move from the bottom of the screen to the top of the screen by animating its frame property.

CGGeometry and Frames

CGGeometry refers to a reference set of methods and data types (C structs) that let you manipulate and control the position and size of elements (such as UIViews) on screen. Three common data structures are used when working with CGGeometry. From the Apple Documentation:

CGGeometry Reference defines structures for geometric primitives and functions that operate on them. The data structure CGPoint represents a point in a two-dimensional coordinate system. The data structure CGRect represents the location and dimensions of a rectangle. The data structure CGSize represents the dimensions of width and height. — Apple Reference Document

The one I will be discussing is CGRect which encapsulates a CGPoint (an x and y coordinate) and CGSize (a width and height). The CGRect struct definition looks like:

struct CGRect { 
CGPoint origin;
CGSize size;
}; typedef struct CGRect CGRect;

CGRect always work in relation to an origin point (0,0) which is usually the top left point on your device screen — at least for views which are the direct subview of a parent ViewController but more on that later. Creating a point at (20,20) would then refer to a point 20 points to the “right” (x-axis) and 20 points “down” (y-axis). You can think of it like the 4th quadrant of a graph.

One other important distinction for the coordinate system is that they are always in reference to their superview. If we had a UIView called UIViewOne which is a subview of the parent UIViewController, UIViewOne will use geometry coordinates relative to that parent. Thus if you were to set the origin to (20,20) you would rightly expect UIViewOne to be 20 points to the right and 20 points down. If you then added another UIView called UIViewTwo as a subview of UIViewOne (2 views removed from the parent UIViewController) then an origin property of (20,20) would make UIViewTwo’s origin at (40,40) in relation to the parent UIViewController’s origin point of (0,0) and (20,20) in relation to UIViewOne.

You can interact with CGRect representations of object coordinates by accessing the frame property of a UIView based object. The frame property returns the corresponding CGRect of where the object is currently placed. In addition, if you modify the frame property by giving it a new CGRect, you can tell the system where the new position of an object should be.

Last, and certainly not least, Apple provides us with a helper method called CGRectMake which given all all of the requisite information will generate a CGRect struct to use as a frame:

CGRect CGRectMake ( CGFloat x, CGFloat y, CGFloat width, CGFloat height );

Creating a Star Object To Be Animated

I chose to create probably the simplest star object ever, with a simple interface that instantiates a new star at an x-coordinate and waits a defined period of time before appearing on screen and an animation method that begins after the same delay.

The star is, aptly, a UILabel with a text property of “.”

I like to opt for simplicity whenever possible and leave the rest up to the imagination. I could’ve gone all out and created custom stars with colors and edges but for this purpose, this is all that is needed to create the desired effect. Changing the size and speed (animationTime) of the star is simple and effective.

Putting It All Together

Now that we know about animations and frames and have an object to animate, we can create a simple movement effect through 2d space by animating a change to an objects frame property. This animation moves a star from its start position towards the top of the screen and then begins the animation again from its original position once complete. The star also fades in over 5 seconds in order to prevent a jarring star appearing immediately on the black background.

Once we have the animation created, all we have to do is create stars randomly on the screen. After some experimentation I decided on creating 3 classes of stars in order to create a feeling of depth and movement. The front most layer are larger stars that move faster, followed by stars in the middle layer which are somewhat smaller and move somewhat slower, and finally stars in the far background which are the smallest and move slowly. Getting the animation and size timing right takes some time but the effect is well worth it!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.