Tag Archives: Programming

Animating Interfaces with Core Animation: Part 2

5 Jan

This is the second in a series of posts I’m writing on animating iOS interfaces using Core Animation. In the previous post I created a planetary orbit demo using nested CALayer objects.

This time I’m going to show how you can dress up a UI by creating a simple effect using an image and Core Animation.

Read on to see more

(more…)

Animating Interfaces with Core Animation: Part 1

4 Jan

One of the greatest things about the iOS platform and applications people see on it is its beauty. Smooth gradients, consistent transitions, and animations that illustrate the transition of UI elements from one state to another. Animations are more than flashy eye-candy; they tell the user what’s happening. If an element is being deleted, instead of it simply disappearing it fades or slides out of view. Unlike traditional desktop or web applications where a “2 items deleted” statusbar message is necessary, these animations are in many cases enough.

Knowing where to start with animations can be a problem for developers though, because there’s many different steps involved. Instead of walking you through it fully here in the blog, I highly recommend you watch the WWDC 2010 videos on the topic. I truly mean it; anything I do here will simply be a rehash of that material, and I don’t see the point in reproducing perfectly good documentation unnecessarily.

  • WWDC 2010 Session 123 – Building Animation Driven Interfaces
  • WWDC 2010 Session 424 – Core Animation in Practice, Part 1
  • WWDC 2010 Session 425 – Core Animation in Practice, Part 2

Read on to see more

(more…)

Fun shadow effects using custom CALayer shadowPaths

16 Nov

Shadowed view using a rectangular shadowPath

I recently had to improve the performance of a few views that utilized CALayer-based shadows on rounded-rect UIView objects. On this particular iPad application, when the device was rotated, the views rotated quite a lot slower than we would have hoped. It wasn’t a show-stopper, but the jerky rotation animation made it look cheap and unpolished. The easiest way to have our cake, and eat it too, was to set a custom CGPath to the layer’s shadowPath property. This told UIKit to set the inside of the path to opaque, reducing the amount of work the rendering engine needed to perform.

// Add background tile
UIImage *bgImage = [UIImage imageNamed:@"embedded_bg.png"];
self.view.backgroundColor = [UIColor colorWithPatternImage:bgImage];
// Add the reference view
UIImage *image = [UIImage imageNamed:@"dccp.jpeg"];
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:imgView];
imgView.center = self.view.center;
imgView.layer.shadowColor = [UIColor blackColor].CGColor;
imgView.layer.shadowOpacity = 0.7f;
imgView.layer.shadowOffset = CGSizeMake(10.0f, 10.0f);
imgView.layer.shadowRadius = 5.0f;
imgView.layer.masksToBounds = NO;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:imgView.bounds];
imgView.layer.shadowPath = path.CGPath;
[imgView release];

The resulting image, as you can see above, has a shadow as you’d expect. But since we’ve declared the shape the path will have, the iPad can drastically improve its rendering performance.

Through that process however, I decided to see what sort of effects I could pull off by passing in a path other than the default rectangular bounds of the layer. Since you can create any sort of path you want, I considered the different effects I could get away with by making non-rectangular paths and using them as shadows. (more…)

Rendering views using CALayer, Part 1

13 Nov

For myDrumPad the main pad buttons are images. I create a UIButton object, and use setBackgroundImage:forState: to customize which image will be used for each state (UIControlStateNormal and UIControlStateHighlighted mainly).  I customize the title label font, shadow and color, and voilà I have a pad button that simulates the look and feel of  a Korg padKONTROL. There’s just a few small problems with it.

  1. The images on the iPad are fairly large, and memory is at a premium.
  2. The size of these buttons can change in portrait vs. landscape. It’s time-consuming to export different versions from Photoshop for the different orientations.
  3. The buttons are sized differently depending on the size of the button grid (e.g. a 3×3 grid of buttons have larger images than 4×4 or 5×5 grids). If I resize these images on-the-fly, then the edges look blurred and aren’t well-defined.
  4. The retina display complicates all of this, meaning I have to have two versions of each image.
  5. I want to be able to customize the buttons to have different colors when you’re on different drum sets.

Because of that long list, simply using an image isn’t good enough. But instead of drawing my images using regular Core Graphics drawing routines, I’m going to use Core Animation Layers, or CALayers, to accomplish the same thing. Ultimately I want my buttons to be able to be animated, to change color, and to feel more “alive” than a static image could accomplish. (more…)

Recovering from bit rot

9 Nov

One of the things that’s hard as a developer is keeping your legacy code up to date.  It’s all too easy to fire-and-forget; write your code, debug it just enough so that it compiles, and then forget it until it breaks again.  I’m guilty of that as well.  In fact, just today I discovered that my continuous deployment configuration for Boomle was broken…for the past 3 months.

After merging my code from a private repo over to Github, it still didn’t work.  After updating the Hudson build configuration to point at the proper repos and to respond to the proper webhooks (to get automatically triggered on a new check-in), it STILL didn’t work.  You see, not only does configuration change, but SDKs and APIs shift out from under you.  The iOS SDK had changed out from under my project, and the Xcode configuration was pointing at libraries and SDKs that no longer were shipped by Apple.

The lesson for me here is this: I need to get off my ass every few weeks to at least look at my source code.  Kick the tires a little, hit a build every now and then, and check that everything is still okay.  Because the longer you wait, the more things can fall apart.  Each one of those issues I mentioned above would have been simple to fix, had I addressed them right away.  But the more problems that build up, the more difficult it is to clean up your code.

As it is, I still need to integrate Game Center with Boomle, and refactor its drawing routines to be more efficient.

Now, I don’t believe in New Year’s resolutions.  Instead, I believe in making resolutions whenever they’re relevant, and sticking to them without the excuse of a New Year to motivate you.  My resolution is to take care of my projects proactively, instead of forgetting them.  Treat it like the quasi-living thing that I’m anthropomorphizing it to be, because even inactive projects need love too.

Using Amazon S3 as your iOS app’s server-side

5 Nov

While developing myDrumPad, I came across an interesting problem for my in-app purchase support. The app allows users to download additional packs of sounds (referred to as “sound packs” in the app) that they can use to tap out songs and rhythms. The sound packs themselves were a collection of CAF-encoded uncompressed PCM audio files, with a single configuration file describing the labels and arrangement of the sound files on the drum pad’s grid of buttons.

I wanted to be able to add additional sound packs without issuing a new release of the app, but since the information describing the sound packs is largely static, I didn’t want to have to worry about maintaining a dynamic server for the app to continue functioning. I wanted it to largely be “fire and forget”.

What I came up with is, I think, a best of both worlds. The app functions without needing me to maintain a server, but I can still dynamically add additional resources to the app instantly.  Read on to find out more.

(more…)

Filtering great ideas to fit my available time (and budget)

19 Oct

I’m an avid “Idea Man”.  I love coming up with new ideas; for iPhone apps, for web apps, and even for real-world inventions.  Most of my ideas only sound great in my head, but when I open my mouth the idea seems to turn sour.  A smaller number of ideas manage to survive the thought-to-word boundary.  An even smaller minority of those ideas manage to make it down onto my “Idea Book” that I use to keep track of all the potential projects I’m going to work on.  Admittedly it’s not so much a single “book” as a collection of binders, scraps of paper, and in some cases 3×5 index cards.

Suffice to say amongst all those ideas, some gems manage to stand out above the rest.  A few I’ve actually finished, such as Boomle and myDrumPad.  The end product is seldom what I’d planned when I came up with the idea, but either due to time constraints, or the project evolving during the course of its development, things change.  Mostly I’m pleased with the end result, but there are some things I wish I had time for.  For instance, I’d like to re-implement Boomle using Cocos2D to make the animations smoother, and maybe add some extras such as obstacles, more challenging levels and Game Center integration.

Unfortunately, while I absolutely love myDrumPad, my original plans for it involved the creation of loops and patterns within the app.  Once I built it and started playing with it in real-time, as opposed to my ideas jotted down on paper, I discovered that the interface — while easy to use for quickly tapping out beats — doesn’t lend itself easily to creating loops.  I could create loops, sure, but my goal was to create an app that could be used in live performances, and sadly the interface just doesn’t lend itself to real-time editing of loops.  That’s not to say that I’m unhappy with myDrumPad.  Sales are going fairly well, and I have a few more updates planned.  I’m still adding additional languages to it using ICanLocalize.com (currently it has native support for English, Korean and French, and Japanese and German are following soon).

One of my constant loves for as long as I have been programming has been music and sound production.  And since I’m a rather unconventional thinker, I’d like to try my hand at an unconventional music interface.  I like the idea that someone without any knowledge of music notation or performance can learn to use my apps to produce the music they hear in their head, and to express themselves in ways they wouldn’t otherwise be able to.

I’m still formulating an idea in my head, but the loop and patterns features I was planning for myDrumPad are going to be built into a new application instead, with a completely different interface.  Like myDrumPad, it will be an experiment to see if producing music in this new UI metaphor will be successful.  It’s hard to explain, so I’m going to wait until I have a more accurate prototype to show.

But this app idea doesn’t exist in isolation.  In my little book of ideas I have several on-the-go prototypes just itching to get started, but since I still maintain a day job (and will for the foreseeable future) my time is limited to a few hours per day, and weekends.  My web-based space game, my photo sharing web application, my sonar-based iPhone utility app…all these ideas are stuck in my head as fantastic ideas I’d love to pursue, if only I had the time.

I’m sure it will be an interesting adventure to see which idea wins out in the end.  Do I build a web-based MMOG space game set in an infinitely-scalable universe?  Or do I build a Core Audio-based iPhone utility?  How do I determine which project has the highest likelihood of succeeding, or at least have the greatest likelihood of being finished in a reasonable time-frame by a single developer?

In an ideal world I’d build all of them.  Unfortunately, as an idea man, I think of ideas of varying awesomeness faster than I can build them.  As long as I require sleep, I suppose I’ll be stuck in this situation.

Building a custom Dashboard-like UIButton

19 Sep

Help overlay showing the Parking Mobility quick start help

As part of the Parking Mobility iPhone app I’ve been building, I wanted to integrate a simple “Quick Start” help guide to show people how to use the app without being intrusive.  I wanted to use the project’s branding as much as possible, and give the user a feeling like they haven’t left the main portion of the app.  So I wanted the user to be comfortable with it, and always have a quick way to close the help window to get back to the app.

In the end I created a little Close button in the top-left corner to mimic the behaviour of the Mac OS X Dashboard widgets.  But I didn’t want to simply add a static image since those don’t scale easily.  Plus I wanted to learn more about native drawing using Core Animation and Quartz2D.

The end result is actually really simple.  I subclassed the UIButton class, and overrode the drawRect: method to use some native drawing primitives.


Reading through the source code, you can see how I split the drawing between two different routines.  First, my layer drawing which draws the border, the circle, shadows, etc is handled using raw CALayer drawing.  The second block, inside drawRect:, draws the lines forming the “X” inside.

Simply add these files to your project, and create a new DNCloseButton object and add it to your view.

If you find any bugs in this code, please let me know and I’ll update this post.  I hope this works out as well for you as it has for me.

Dealing with MKMapView’s Google logo with translucent toolbars

12 Sep

One of the iPhone applications I’ve written, Parking Mobility, is primarily a map-based application.  Since the iPhone’s screen is so small, we want to maximize the screen real-estate while still providing navigation bars for users to interact with.  To that end, the app uses a black-translucent navbar and toolbar at the top and bottom of the screen.  In the past this has never been a problem, and most mapping applications do the same thing.  I recently submitted a huge update to the app which is a complete re-write as a 100% native Objective-C based application (all vestiges of PhoneGap having been removed).  With this latest submission though, we’ve run into problems.

Read on for more, and what I’ve done to (hopefully) get around this.

(more…)

Silent no more…

3 May

Wow the past few months have been quite a wild ride, and a ton of things have happened!  So much has gone on and I’ve been writing so much software that I haven’t had the time to blog about it.  In the time I’m not writing software, I’d rather spend it with my wife than spend it writing about the software I’d written.

Over the past few months, while the PhoneGap team started a major refactor of their codebase, I spent some time learning more about Objective-C and UIKit, and discovered that writing native software on the iPhone is a heck of a lot easier than I’d previously expected. It shouldn’t have surprised me, because I’ve heard rave reviews from developers I have a great deal of respect for, and it also shouldn’t come as a great shock that Apple treats their developer SDKs with the same degree of polish and attention-to-detail that they do to their hardware. So while I was working with PhoneGap I’d contributed a number of plugins exposing the iPhone’s native UI elements to JavaScript-based apps, I’ll no longer be updating or adding any new plugins.

While my blog was collecting dust, I also finished a PhoneGap-based app, Parking Mobility, and while it was nice to start the project in familiar languages like HTML and JavaScript, a ton of time ended up getting eaten up chasing random bugs, memory leaks, and strange UI behaviours that required odd work-arounds to eliminate.  In the end I discovered I’d spent more time getting the application to market than if I had built it in native code.  Starting this past weekend I’ve begun doing just that, writing the application in UIKit and Objective-C in order to get more performance and a better user-experience out of the app than we have currently.

One of the other big reasons why I haven’t been as chatty on my site as usual is, of course, the launch of the iPad and the iPhone 3.2 SDK.  I decided to hit the ground running with this platform, and used this new SDK as my playground for learning more native development skills.  I developed two applications for the initial launch of the iPad, Boomle and myDrum Pad.

Boomle is an easy-to-play game featuring peaceful sounds, low-touch interaction, and an addictive gameplay.  It was a lot of fun to build, and got me started working with OpenAL, manually drawing displays, and dealing with real-time games.

myDrum Pad in contrast is an interactive drum pad that aims to allow people to tap beats out with a variety of sound packs along to music, or create their own riffs.  It’s still in active development, but this has been a blast.  I’m developing it with CoreData, OpenAL sound playback, multi-touch displays, In-App purchase and asynchronous downloads from Amazon S3.  It’s a highly dynamic UI with a smooth user experience.  It’s also the first iPhone project that I’m directly involving a graphic designer with the whole process, and once we get a beta ready, I’m sure you’ll like the screenshots and demo images we’ll be putting up.

Last, and certainly not least, I’ve changed roles in my day job at Sophos, and am working once again in the Email Security team developing our Email Security Appliance.  I get to play with all sorts of complex problems, web-based administration interfaces, and pretty much every technology under the sun.

Now that these projects have all stabilized, I’ll hopefully be blogging more about Objective-C, Javascript web applications, and technology in general. Plus Summer’s quickly approaching, so hopefully I’ll have some pictures of my motorcycle and any trips my wife and I take this summer up here soon.