May 23 2011

TechNote 9 – Animating Views

Animating views in iOS using blocks is a great way to simplify your code. However, the current API has one drawback; the default is to disable user interaction during the animation. e.g.

The “old” way, pre-blocks

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:HIDE_DURATION];
[self _hide];
[UIView commitAnimations];

With Block:

[UIView animateWithDuration:HIDE_DURATION animations:^{ [self _hide]; }];

Much neater, but as I mentioned, with blocks user interaction is disabled by default (whereas it wasn’t in the “old” way). To enable user interaction, you need to supply the UIViewAnimationOptionAllowUserInteraction option (plus the default ones of UIViewAnimationOptionCurveEaseInOut and UIViewAnimationOptionTransitionNone), but then you can’t use any of the shortcut methods:

With Blocks and User Interaction enabled:

[UIView animateWithDuration:HIDE_DURATION
     delay:0
     options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone
     animations:^{ [self _hide]; }
     completion:^(BOOL finished) {}
];

This is too much unnecessary code for me (i.e. the empty completion block), so I decided to create a simple category that enables user interaction by default:

UIView+InteractiveAnimation.h

+ (void)animateWithInteractiveDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

+ (void)animateWithInteractiveDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;

UIView+InteractiveAnimation.m

+ (void)animateWithInteractiveDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion {
    [UIView animateWithDuration:duration
        delay:0
        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone
        animations:animations
        completion:completion
    ];
}

+ (void)animateWithInteractiveDuration:(NSTimeInterval)duration animations:(void (^)(void))animations {
    [UIView animateWithDuration:duration
        delay:0
        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone
        animations:animations
        completion:^(BOOL finished) {}
    ];
}

So now I can have clean animation code, with user interactions:

With Blocks and User Interactions using UIView+InteractiveAnimation category:

[UIView animateWithInteractiveDuration:HIDE_DURATION animations:^{ [self _hide]; }];

Enjoy…


Feb 14 2011

Tech Notes

These Tech Notes are generally very short and to the point. They are mainly reminders to myself about how to do things, but others may find them useful too.


Feb 14 2011

TechNote 8 – FIXME

Just came up with a handy macro to remind myself where things in my code need fixing;


#define FIXME(fmt, ...) int FIXME = 1;NSLog((@"FIXME %s (%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

This is defined in one of my common header files and used as follows:


FIXME(@"Don't forget to fix this");

Then every time I compile, I get a nice annoying warning, prompting me to fix my code:


MyFile.m:22: warning: unused variable 'FIXME'

as well as a message in the console every time I run:


FIXME -[MyFile someMethod] (22) Don't forget to do this


Nov 29 2010

Cindy – The Social Media Magazine

Cindy on the iPad is my current project in development.

Cindy will be a Social Media Magazine for the iPad, incorporating RSS reading, Twitter and Facebook, all in the one app, presented as a beautiful glossy magazine.

I’ll be posting updates on Cindy’s site so go and check it out for all the latest gossip!


Jun 13 2010

Times Tables App

Times Tables

I am pleased to announce the release of the Times Tables Timing Challenge iPhone application.

Master your multiplications tables with this easy-to-use education app. With timed quizzes, multiple accounts, multiple difficulty levels and report cards, learning the Times Tables has never been more fun!

See the Times Tables Timing Challenge page for more information.


Jun 10 2010

Cowboys versus Fruit?

When I was a kid, we used to play Cowboys and Indians. This was one of the most popular Good Guys verses Bad Guys style of game amongst my friends, with smoking cap guns and rubber tipped arrows. Probably not very Politically Correct today but very popular back in the day.

This inspired my latest idea for a new app game. Something along the lines of Cowboys and Indians, maybe Custer’s Last Stand, with cowboys defending a circle of wagons while marauding Indians attacked with flaming arrows. But this got me thinking …. would such an app get approved, even though it is based on actual historical events? Is it politically correct enough for Apple to approve? Or in this day and age, when minority groups rule, would a few people take offense and the app get pulled? Not having lived in the US, I’m not sure of the current political situation with regard to Native American Indians. I’m sure that if I build an app here in Australia, where a bunch of white settlers went around shooting the indigenous population and stealing their children (which also did really happen) it would not get approved. Maybe heavily armed Special Forces operatives storming through the mountains attacking dudes with towels on their heads and any passing goats they come across? (currently happening?) How about an army of blond haired, blue eyed Arians rounding up those with a different faith and herding them into trains? Probably not. (Is there anyone left that’s not yet offended?)

Maybe this is why we have so many Zombie games. Zombies tend not to have much support, even amongst minority groups. And if you get bored with blasting Zombies yourself, what could be more politically correct than Plants verses Zombies? Not much chance of complaints there (other than from vegetarian necrophiliacs – and they tend not to crave publicity).  Ninjas seem a pretty safe bet too with countless Ninja games currently available in the app store.  And then there is of course, Ninjas verses Zombies (doubly politically correct?). Not to be outdone by the plants, fruit takes on the fight in Ninjas verses Fruit or the educational Math Ninja attacking tomatoes (again, not many groups to offend there). Of course, blasting aliens and robots is also a fairly safe and well-established theme with literally thousands of “shoot the alien” games (intergalactic travelers being another rather poorly represented minority group – at least as far as I can tell).

So maybe my Cowboys verses Indians theme is just too politically sensitive to risk months of development in a game that may get rejected. Maybe I should take inspiration from the current game themes and include some fruits or vegetables verses some sort of aliens or machines. That way, there’s much less chance that my game will cause offense to some minority group and get rejected. So fruits verses machines it is. Maybe something like Apples for the fruit and Android robots for the machines. Surely that’s a safe bet – who would possibly complain about that?


May 17 2010

TechNote 7 – iPhone Ringtones

A quick note on creating your own Ringtones for your iPhone from music in iTunes. This also works for Alarm sounds when you get fed up with waking up to Marimba!

This is definitely not as easy as it should be and there may be simpler ways, but this should work.

  1. Start iTunes and find the song you want to convert. (It must be an MP3.)
  2. Right-click the song and choose Get Info.
  3. Click the Options tab.
  4. Check the Start Time and Stop Time boxes, then enter times for each (no more than 30 seconds apart, the maximum length for a ringtone).
  5. Click OK, then right-click the song again and choose Create AAC Version. You should immediately see a new 30-second version of the song. If the Create AAC Version option isn’t there, try the Advanced menu. If its not there either, check your Preferences->General->Import Settings… and ensure you have Import Using set to AAC Encoder.
  6. Drag that version out of iTunes and into the folder of your choice.
  7. Delete the 30-second version from iTunes and undo the Start Time/Stop Time changes to the original.
  8. Open the folder containing the 30-second AAC file you dragged out of iTunes, then change the file extension from .m4a to .m4r.
  9. Double-click it and it immediately gets added to iTunes’ ringtone library.
  10. Finally, sync your iPhone. When it’s done, you can head into the settings and select your new ringtone.

May 15 2010

TechNote 6 – Roll your own static libraries

In TechNote 2, I outlined how to use static libraries from a Cocos2d project in one of your own projects, i.e. without actually copying the source into your project. In this technote, I describe how to package up some of your own code into a stand alone project and make it available to your other projects in the form of a static library. This assumes you have set up Xcode as described in TechNote 1 and are familiar with the procedures described in TechNote 2.

I have a utilities project, RMAUtils, that contains (surprisingly) utility classes and macros. I also have a Cocos2d project, RMACocos2d that builds come reusable controls based on Cocos2d and also uses RMAUtils.

Both projects were started as Cocoa Touch Static Library projects (New Project -> Library) and so they each produce static libraries named libRMAUtils.a or libRMACocos2d.a.

I also have an application project that uses my static libraries (libRMAUtils.a, libRMACocos2d.a) as well as Cocos2d. These (3) libraries were all included in the application project as described in TechNote 2.

This seemed to work fine for a while until I started using Categories in my RMAUtils project. After a bit of searching, I found I needed to include the following in the Linking section of the Target of my app.

Other Linker Flags: -all_load -ObjC

(Note the -all_load flag only seems to be needed on the device, not the simulator.)

However this caused multiple definition errors in the linking stage of the build.

It turned out I made the mistake of including libRMAUtils.a and Cocos2d static libraries in my RMACocos2d static library project in the “Link Binary with Libraries” stage of TechNote 2.

The solution simply involved not adding these libraries to linking stage in the static library projects, i.e. don’t do step 4 in TechNote 2 when building static library projects. The other steps are still required when setting up static library projects that rely on other projects.

The linking step (step 4) is only required in the final application project.


May 15 2010

TechNote 5 – Splitting Large Files

I recently wanted to back up a large file (> 4GB) to DVD on my Mac. The solution:

split -b 2048m myLargeFile.dmg

This produces a bunch of 2GB files names xaa, xab, xac … etc

If I need to recreate the original file, copy all the files back to my Mac, then:

mv xaa recreated.dmg
cat xab >> recreated.dmg
cat xac >> recreated.dmg


May 14 2010

TechNote 4 – Generating model classes from Core Data with mogenerator

Instructions on generating model classes from Core Data model using mogenerator.

In a terminal window:

cd /Users/rob/workspace/iphone/myProj/myProj.xcdatamodeld

mogenerator -m myProj.xcdatamodel/ -O ../Classes/

The version of mogenerator I use (1.6.1) was from:

http://sourceforge.net/projects/redshed/files/mogenerator/