This year we’ve completely rebuilt C4. It’s more solid, more flexible and definitely more badass than before. In doing so, we’ve changed a LOT.

Here is a brief overview of those changes.


C4 is now 100% Swift (2.0). No more square brackets. Throughout the api we’ve taken advantage of all the new facets of Swift, including things like tuples, optionals, initializer inheritance, initial stored values, generics, subscripts, closures, new control-flow statements (e.g. for-in), advanced operators… I could go on.

Keeping with our fundamental guidelines for C4, our new API is very Swift-like (similar to how the old version was very ObjC-like). So, if you’re learning C4 you’re actually learning Swift. Or, if you’re experienced with Swift, then picking up C4 will be very easy.


Everywhere! We’re now using blocks in almost every part of the api.

Creating an animation used to look like this:

circle.animationDuration = 1.0f;
circle.animationOptions = AUTOREVERSE | REPEAT; = CGPointMake(384, 512);

You would set the duration, then any changes that happened to properties after that would create individual animations and then run.

Now, animations are their own objects that accept blocks of code to execute:

let anim = C4ViewAnimation(duration: 1.0) { = ...
circle.fillColor = ...

Check out the new way of creating animations with blocks in the next section.

Creating a delay used to look like this:

[self runMethod:"aMethod" afterDelay:0.5];

Now, we do things like this:

delay(0.5) {

These are just 2 examples of how C4 uses blocks, and there are a lot more examples I could show. However, I just want to point out that significant change in our approach to a block-based api. Throughout the rest of this article you’ll start to see how blocks appear everywhere.


C4 used to rely heavily on implicit animations, but now we’ve shifted to executing blocks of animations. Creating an animation used to look like this:

circle.animationDuration = 1.0f;
circle.animationOptions = AUTOREVERSE | REPEAT; = CGPointMake(384, 512);

You would set the duration, then any changes that happened to properties after that would create individual animations and then run. This approach was pretty decent for V1, but getting into complex animation sequences was very tricky… For example, wanting to have 2 separate animations happen with distinct timing on the same object was a bit of a hassle:

circle.animationDuration = 1.0f;
circle.animationOptions = AUTOREVERSE | REPEAT; = CGPointMake(384, 512);
circle.animationDuration = 0.5f;
circle.fillColor = ...

In cases like this, the durations would collide with one another because they were being set in the same method.

Now, animations are their own objects and can handle changing a variety of properties of different objects, etc., rather than being restricted to the property changes of individual views.

let anim = C4ViewAnimation(duration: 1.0) { = ...
circle.fillColor = ...
anim.autoreverses = true
anim.repeats = true

Property changes for both the circle and the square will inherit the autoreverse/repeat characteristics of the animation. We can also store that animation as a variable and use it throughout our app (e.g. whenever an event occurs).

Animations also have completion blocks. So, if you want to do something with an object after it has finished animating you can do something like this:

let anim = C4ViewAnimation(duration: 5.0) {
self.canvas.backgroundColor = C4Blue
anim.addCompletionObserver {
self.canvas.backgroundColor = C4Pink

This will animate the background of the canvas for 5 seconds, then when that’s complete it will switch immediately to another color.

Previously, animating a group of objects was pretty heavy-handed. You’d create all your animation code for every case, stick that into a method, then call all the methods sequentially from another method… It might have looked something like this:

- (void)animateMoveCircle {
circle.animationDuration = 1.0
circle.options = AUTOREVERSE | REPEAT = …
- (void)animateFillCircle {
circle.animationDuration = 0.5
circle.options = AUTOREVERSE | REPEAT = …
- (void)animateMoveRect {
rect.animationDuration = 1.0
rect.options = AUTOREVERSE | REPEAT = …
- (void)animateFillRect {
rect.animationDuration = 0.5
rect.options = AUTOREVERSE | REPEAT = …
- (void)animateCircleRect {

Now, it looks something like this:

let move = C4ViewAnimation(duration: 1.0) { = … = …
let fill = C4ViewAnimation(duration: 0.5) {
circle.fillColor = …
square.fillColor = …
let animations = [move, fill]for anim in animations {
anim.autoreverses = true
anim.repeats = true
let group = C4ViewAnimationGroup(animations)group.animate()

And, when you animate the group, everything initiates at the same time.

C4 also has sequences.

Instead of something like:

[self animateMoveCircle];
[self runMethod:"animateMoveRect" afterDelay:1.0];
[self runMethod:"animateFillCircle" afterDelay:2.0];
[self runMethod:"animateFillRect" afterDelay:2.5];

We now do:

let sequence = C4ViewAnimationSequence(animations: [move,fill])

And, each animation in the array executes after the previous one has completed.


We’ve also overhauled the interaction mechanism. Where we once took advantage of a combination of touch methods as well as gestures, we now stick solely to adding gestures to objects. It’s a nice, cleaner way of handling interaction.

In the past, every object was implicitly observing touches through methods like:

-(void)tapped:(CGPoint)location {
//where you could subclass and override this method
-(void)move:(CGPoint)location {
//where you could subclass and override this method

Internally, these methods looked like:

- (void)tapped {
- (void)tapped:(CGPoint)location {
[self postNotification:@”tapped”];
[self tapped];
-(void)move:(CGPoint)location {
NSUInteger _ani = self.animationOptions;
CGFloat _dur = self.animationDuration;
CGFloat _del = self.animationDelay;
self.animationDuration = 0;
self.animationDelay = 0;
self.animationOptions = DEFAULT;
CGPoint displacementFromCenter = CGPointMake(location.x — self.width/2 , location.y — self.height / 2); = CGPointMake( + displacementFromCenter.x, + displacementFromCenter.y); [self postNotification:@”moved”];
self.animationDelay = _del;
self.animationDuration = _dur;
self.animationOptions = _ani;

We found that the overhead of 2 separate conceptual interaction models (i.e. touches and gestures) was inappropriate. Also, this approach required subclassing an object in order to customize a reaction to tapping or moving, etc. Furthermore, adding block-based gestures makes it so easy to handle interaction.

Now, we do the following:

let square = C4Rectangle(frame: C4Rect(0,0,100,100))

square.addTapGestureRecognizer { location, state in
self.canvas.backgroundColor = randomColor

Where the color of the canvas changes when a square is tapped.


canvas.addPanGestureRecognizer { loc, trans, vel, state in = loc

Where the position of a square is centered to the user’s finger as they drag around the canvas.


Say you want to know when something has happened, for example you want to know when a movie has finished playing, or when a method has run, but you don’t want to have a hard reference to an object (or set of objects) in that method. You use an observer.

In the old version of C4 you could tell any object to listen for a message, and specify a method to run when that message comes through. The syntax used to look like this:

[self listenFor:@"aMessage" andRun:"aMethod"];
[self listenFor:@"aMessage" fromObject: anObject andRun:"aMethod"];

And, to send a message an object could do the following:

[self postNotification:@"aMessage"];

However, this technique suffered from the same kind of thing as the touches approach above: you often had to subclass to properly change an object’s behaviour. Again… Blocks to the rescue!

Instead, we now do the following:

on(“aMessage”) {
//do something
on(“aMessage”, from: anObject) {
//do something

And, posting is just as easy:


Abstraction: Core & UI

The entire api has been significantly abstracted. For example, we used to have a class called C4Control that was the base class for all visual objects in C4. That class had just over 1000 lines of code… It was huge.

Now, that class is replaced with a basic C4View (~600 lines, incl. comments) and any non-critical or conceptually separate components of that class have been abstracted into extensions. For example, the following extensions are separate files:


This makes the api easier to read, makes the structure more clear, and is just generally less heavy-handed than before.

On top of this approach, we’ve separated code into two categories.

There are a core set of classes that represent the objects and structures necessary to work with C4. Included in this are any elements that are not related to a user’s direct experience, but are necessary for the function of the framework.


All visual / media objects are part of the UI section of the project. These include controllers, filters and extensions that have to do specifically with visible or audio media.


UIKit Extensions

Finally, we’ve included a bunch of extensions that make working between C4 and UIKit easier. Though not exhaustive, these extensions make a significant difference when needing to add views, convert points, and so on…

UIViewContoller now has a canvas object. This is a C4 version of the object’s view property. Where the following:


… will return a C4View that encapsulates the native view of the controller.

This makes things easier when changing the background color of a native viewController’s view. Instead of:

aUIViewController.view.layer.backgroundColor = UIColor.redColor().CGColor

You can do:

aUIViewController.canvas.backgroundColor = red

A C4View is actually a wrapper around a UIView. So, you can’t directly add a view to another view… To handle this (and make things consistent) we’ve included add and remove methods that make things work between UIView and C4View.


This add method also implicitly handles optionals.

There are also:

add([subviewArray]) //for adding multiple views

Creating a UIColor or a CIColor is possible:


Casting bewteen basic structure types is possible too:


… and of course, the other way around:



We’ve run through a basic set of changes between the first and second versions of C4. There are a TON more changes that we’re proud about, but too many to dive into.

The new version is badass.

Download it.

Use it.

Let me know what you think.

Code, Creatively. An open-source API for iOS.

Code, Creatively. An open-source API for iOS.