December 2010

Old Year, New Year, Old Stuff, New Stuff!

Filed in iDevBlogADay, Miscellaneous | Comments Off on Old Year, New Year, Old Stuff, New Stuff! |

Old Year, Old Stuff

I have been an independent developer for over twelve years, using a variety of tools, platforms, and languages. I really love being on my own, even through the slow periods when I wondered if I would find any new projects to work!

Breaking away from corporate life might not be for everyone, but if you are thinking about it, I encourage you to keep working towards that goal. Being independent while my kids were growing allowed us to do many things as a family that I would not otherwise have been able to do. It also put me in a position to work on some very cool projects for different clients over the years.

Old Year, New Stuff

Twelve months ago, I set a goal of having close to half my work be iOS based by the end of the year. I did not quite reach that goal, but I can definitely see it happening in the near future.

I have really matured in my iOS development by hanging out with very smart and sharing people at 360iDev conferences, local user groups and meetups, and through twitter. Thanks to all who taught, wrote, or otherwise shared great stuff!

New Year, Old Stuff

I have gone through many changes in life, both personally and professionally, but very few have been abrupt ones. I still expect to continue on in some fashion with projects I have been working this past year. As some major projects from the past year wind down this year, it will be interesting to see what comes next.

New Year, New Stuff

This coming year will be one of those gradual changes as I move into more and more mobile development, both iOS and Android, over the coming months. I anticipate being very busy for the first few months of the year, and then seeing what happens.

iDevBlogADay.com

Today’s post marks four complete months for my participation in iDevBlogADay, and with the new work I will be involved with over the next few months, this seems an appropriate time to hand over my coveted Sunday slot to the next victim. I’ve really enjoyed being a part of iDevBlogADay.com — it has been the primary support technique to get me writing regularly again, and for that I am very thankful.

Participating has taught or reminded me of several things:

  • Just like software, good writing is work;
  • Writing usually takes longer than I think and rarely turns out exactly like I planned;
  • There is nothing like a deadline to motivate me to action;
  • Writing about what I am learning helps me understand it better;
  • The developer community in general, and the iOS developer community in particular is great!

Thanks Miguel!

Miguel, thanks so much for the work you put into setting up and maintaining iDevBlogADay, I appreciate it very much. For those who have read, commented on, and retweeted my posts — thank you, I hope you found some useful nuggets along the way.

I still plan on posting twice a month, though not on Sunday. You should subscribe to my blog and hold me accountable to this.

Please follow me on twitter if you are interested in what comes of all this new stuff!

Merry Christmas and Happy New Year!

Animating Multiple Virtual Pages Using a NIB-based View

Filed in iDevBlogADay, iOS Development | Comments Off on Animating Multiple Virtual Pages Using a NIB-based View |

Today’s post is a simplified version of some work I’m doing for a client.

For the client app, I need to browse a set of data using a NIB-based view, but do so by swiping left and right in the context of a parent view — a similar effect as Apple’s weather utility app. I didn’t explore how Apple actually does it, but the method I am using is pretty straightforward.

Overview

Demo2010Dec19_pic1.pngThis simple app displays a view for a single item at a time from an ordered list of simple domain objects. A UISwipeGestureRecognizer detects swipe events which are used to animate items on and off the parent view.

The previous view is off screen to the left, and the next view is off screen to the right. Both of these are preloaded so that when a swipe event is recognized, there is no delay while loading data for the item to be animated onto the parent view. The app cycles through three instances of the same NIB-based view controller as the user swipes.

For instance, given a list of 7 items, the app starts in this state:

  • The center view displays item A;
  • The view off screen to the right is preloaded with item B;
  • The view off screen to the left is preloaded with the last item, item G;

In this state, when a left swipe event is recognized, I want it to be interpreted as “move the currently displayed item (A) to the left and show me the next item (B)”. What happens is this:

  • The position of the center view is animated to the left off screen position;
  • The position of the right view is animated to the center on screen position;
  • The old center view becomes the new left view;
  • The old right view becomes the new center view;
  • Since the old left view is “pushed” farther to the left, it becomes the new right view;
  • The new right view is loaded with the appropriate data from the list.

A mirrored set of events happens on a right swipe event. (The app treats the list circularly, so there is no right or left edge of items.) The app also includes a tap recognizer which is used to update the tap count for each item to demonstrate how you can maintain state as views are cycled.

Handling Gestures

Each instance of SampleViewController has three gesture recognizers, swipe left, swipe right, and tap. Each also retains a reference to it’s currently displayed item when it is loaded.

The behavior for tapping is simple. When a tap is recognized on a view, the tap count for that view’s item is updated. Nothing needs to happen outside the current view and item.

The behavior for swiping is slightly more involved. Since a swipe is supposed to initiate animating the current view off the screen and a new view into the center, it would be messy for the current view to handle the animation. The best solution is to have the parent view handle the animation, since it already owns all the items and views necessary.

The cleanest way to accomplish this is by creating a simple protocol for delegating the behavior. SampleViewController.h includes the protocol definition, and adds an ivar for the delegate itself.

SampleViewController.h

#import <UIKit/UIKit.h>
#import "SampleData.h"

@class SampleViewController;

@protocol SampleViewControllerDelegate
- (void) handleSwipeLeftFrom:(SampleViewController *) source;
- (void) handleSwipeRightFrom:(SampleViewController *) source;
@end

@interface SampleViewController : UIViewController {
    UILabel *sampleIdLabel;
    UILabel *nameLabel;
    UILabel *tapCountLabel;
    UIImageView *imageView;

    SampleData *sampleData;

    id<SampleViewControllerDelegate> delegate;

    UISwipeGestureRecognizer *swipeLeftRecognizer;
    UISwipeGestureRecognizer *swipeRightRecognizer;
    UITapGestureRecognizer *tapRecognizer;
}

@property (nonatomic, retain) IBOutlet UILabel *sampleIdLabel;
@property (nonatomic, retain) IBOutlet UILabel *nameLabel;
@property (nonatomic, retain) IBOutlet UILabel *tapCountLabel;
@property (nonatomic, retain) IBOutlet UIImageView *imageView;
@property (nonatomic, retain) SampleData *sampleData;
@property (nonatomic, retain) id<SampleViewControllerDelegate> delegate;

- (void) loadSampleData:(SampleData *) aSampleData;

@end

and in the implementation simply forwards to the appropriate method of the delegate:

SampleViewController.m snippet

- (void)handleSwipeLeftFrom:(UISwipeGestureRecognizer *)recognizer {
    [delegate handleSwipeLeftFrom:self];
}

- (void)handleSwipeRightFrom:(UISwipeGestureRecognizer *)recognizer {
    [delegate handleSwipeRightFrom:self];
}

- (void)handleTap:(UITapGestureRecognizer *)recognizer {
    self.sampleData.tapCount += 1;
    [self updateTapCountLabel];
}

The delegate owns the three instances of SampleViewController, so is able to properly manage the animation between views:

Demo2010Dec19ViewController snippet (SampleViewControllerDelegate implementation)

- (void) handleSwipeLeftFrom:(SampleViewController *) source {
    if (source == centerSVC) {
        [UIView animateWithDuration:SLIDE_DURATION
                         animations:^{
                             centerSVC.view.frame = leftFrame;
                             rightSVC.view.frame = centerFrame;
                         }];

        // move untouched view to other side, and adjust names for next cycle
        leftSVC.view.frame = rightFrame;
        SampleViewController *tempSVC = centerSVC;
        centerSVC = rightSVC;
        rightSVC = leftSVC;
        leftSVC = tempSVC;

        // cache next sample
        currentIdx = [self checkIdx:currentIdx+1];
        int rightIdx = [self checkIdx:currentIdx+1];
        [rightSVC loadSampleData:[samples objectAtIndex:rightIdx]];
    }
}

More to be done

There is much that can easily be done to enhance this example, some of which I will be adding to my client’s app. Things like:

  • Adding a UIPageControl at bottom
  • Adding fade-in/fade-out toolbars for extra navigation (like the Kindle App)
  • Implementing momentum on swiping so fast swiping moves past multiple views

Hopefully this helps someone get over the hurdle of animating between sibling views. I know I made several simplifications to my original code while preparing the sample code for this blog.

You may download the sample project and use the code however you wish.

Merry Christmas!!

I wish all of you a very Merry Christmas.

Make sure you take time to relax with family and friends this week, but also take some time to read and consider the original Christmas story.


We all need the support of others to do our best. Find other like-minded developers that will provide encouragement and motivation through local user groups, regular conferences or meetups. This post is part of iDevBlogADay which has really helped me stay on track with my writing and my iOS projects.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!

Think, Think, Think…

Filed in iDevBlogADay, Miscellaneous | Comments Off on Think, Think, Think… |

Think, Think, Think...

Think, Think, Think…

One of my favorite shows to watch with my young children was Winnie The Pooh — perhaps because I had good memories of watching the classic TV specials from when I was a child.

I loved the simple, happy nature of Pooh, but one downside of being stuffed with fluff is that it can be hard to think. Pooh occasionally worked very hard at it, with very limited results. I’m pretty sure my head isn’t stuffed with fluff, but some days my thinking doesn’t seem to get me any farther than Pooh’s did.

Lost in Thought — An Incredible, Productive Day

In developing software, my primary tool is my mind. Languages, frameworks, IDE’s, and editors all are important — but without the right mind to use them, and the right frame of mind, they are worthless.

My family can tell you that watching me work some days is incredibly boring. Much of those days is spent staring at the screen, at some scribbles on notepaper, or blankly into space. Those are often the days where I make the most progress.

My most productive days are when I’m so deep in thought that I don’t even remember to eat. I love those days. It’s like I can see the entire program as a single entity in my mind–I can turn it over and around, zoom in and out, pull one part out, graft something new in–it’s a incredible feeling. I wish they happened more often!

Holding it in your head

Paul Graham describes that feeling as “Holding a Program in One’s Head“. He writes:

They do more in their heads: they try to understand a problem space well enough that they can walk around it the way you can walk around the memory of the house you grew up in. At its best programming is the same. You hold the whole program in your head, and you can manipulate it at will.

He goes on to list ways to help load the entire program into your head. I may quibble about some items, but the point is valid. In order to get to that incredible, lost in the world of my program point more often, I need to figure out deliberate steps that move me away from Pooh-thinking and into that magical place.

From Pooh to TRON

There are a number of tactics I use to de-fluff my mind and achieve TRON-ness with my program, but none of them work every time, and each of them are subject to exceptions.

Working at a consistent level

  • I try to stay at a consistent level of abstraction as long as possible, switching costs between working on high-level designs and low-level implementation details can be high.
  • Rather than switching back and forth between competing projects throughout the day, I try very hard to spend most of the day on a single project — even if it is not the exact same task.

Managing distractions

  • Some interruptions are predictable, so preempt them and deal with them before they attack. (If you work at home, this may mean keeping up properly with your share of household duties before you begin.)
  • Have a notebook or software tool that allows you to quickly record any unrelated items demanding attention. Do not do any real thinking about it, simply record it. Once recorded, dismiss the thought and go back to work, those items are attacks on your concentration — do not give ground. (This only works if you have a reliable system for addressing those items, otherwise your mind will not let go.)
  • After you finish a session, deal with the items you recorded appropriately if necessary. That way you train yourself to trust that you really will “deal with that later”.
  • Schedule times or days where coworkers or family know you need to be left alone, in cooperation with them of course! On-going communication is key.
  • If twitter, facebook, news readers, or email keep pulling you away — just STOP IT.

Achieving Flow quickly

  • When you finish a session, or are interrupted, record what you are thinking or doing so that you don’t lose all your context. (See the excellent advice in the post “the interruptible programmer“.)
  • Use music, headphones if necessary. I listen to a lot of different kinds of music, but my “flow” music tends to fade into the background quickly and support my thinking, rather than require me to pay attention to it directly. For me, that usually means minimal or no lyrics, but everyone is different in that regard.
  • If you are actively working on code, then leave it in a mildly broken state. Put some notes directly in the source file where you left off so it won’t compile, add a failing unit test, something to draw your attention back to the point you left.

Manage your expectations

I don’t believe it is possible to be so consistent at your work, that you never suffer from Pooh-thinking days. So don’t set your expectations so high that your disappointment becomes a serious distraction all by itself.

You goal should be improvement, and perhaps even that “perfect” day — but don’t let the fluffy-head days get you down. There’s a good chance tomorrow will be a better day.


We all need the support of others to do our best. Find other like-minded developers that will provide encouragement and motivation through local user groups, regular conferences or meetups. This post is part of iDevBlogADay which has really helped me stay on track with my writing and my iOS projects.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!

Open Source iOS CoverFlow Implementations

Filed in iDevBlogADay, iOS Development | Comments Off on Open Source iOS CoverFlow Implementations |

For my personal iOS development, I have a technical experiment and exploration todo list. It includes techniques I need to get better at, open source packages to investigate, that sort of thing.

I try to keep the items on the list small enough to do enough prototyping in a single evening to satisfy my curiosity. That way I am willing to move on during my next exploration session. The point is not usually proficiency, but enough familiarity to decide if the technique or framework merits further study. I often keep the code around as a reference, but it is definitely throwaway code, so it’s in a separate folder than “real” code.

One of the items on my list was to find and investigate CoverFlow clone examples floating around the intertubes. I found several that were based on Apple’s private APIs or were old enough that I was not interested. But, I did find two that I spent some time investigating.

OpenFlow, a CoverFlow clone developed during iPhoneDevCamp

The first was OpenFlow by Alex Fajkowski, released at iPhoneDevCamp in August, 2009. It is hosted on GitHub, but it does not look like it has been updated since then.

There is sample code included with the OpenFlow download, but it does not have a simple, quick-start example to get an initial feel for the package. Fortunately, others have written posts with some simple examples, two I looked at were:

A simple example by Julios Barros’ (@juliobarros).

And another simple example, but with more pictures and step-by-step details.

I liked OpenFlow well enough, but the current implementation did not allow for flicking through multiple covers. It behaves a little more like iTunes on the mac, not like browsing albums on the iPhone iPod app. Fortunately, my other “find” did have better flicking behavior, with tweakable momentum settings.

FlowCover, an easy to use OpenGL ES based CoverFlow clone

My other “find”, FlowCover by William Woody is essentially one OpenGL ES class with a simple helper class for data caching.

I like simple. Since I am likely to tweak the behavior of whatever I find, the simpler and cleaner the starting point — the better.

I added the two classes to my prototyping base project, and I was off and running. FlowCover works pretty much as expected, behaving smoothly and simply. The only change I made to FlowCover.m was to allow for different scaling when in landscape and portrait modes. Other than that, it worked just as I wanted.

Conclusion

If you are interested in adding some Cover Flow type behavior to your app, I recommend checking out both projects.

OpenFlow is based on UIKit, and has more features than FlowCover.

FlowCover is based on OpenGL ES, has few features, but behaves a little more like I expected Cover Flow on an iPhone to behave.

Either is a good choice, but my needs are simple enough right now that I think I will be using FlowCover.


As an indie developer, one of the best things you can do is to find like-minded developers that will provide encouragement and motivation while pursuing a commitment. A great collection of indie iOS developers have helped me stay on track, many of them are either developers associated with iDevBlogADay, or those I have met through the 360iDev conferences. I also encourage you to find local NSCoder nights, developer meetup groups, or other user groups to keep your motivation on track. If there aren’t any meeting locally, try to find one other developer and start one.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!