Custom fonts on iPad and iPhone

Just incase you didn’t realise, with iOS 3.2 (iPad) and above you can load in custom fonts and use them with a standard UIFont object. There are a few catches… The font must be in the following format: –

  • OpenType Format (OTF)
  • TrueType Format (TTF)

Once you’ve dragged your chosen font file into an Xcode project, the next step is to add a line into the application’s Info.plist file. Add a new key UIAppFonts and make it an array. Expand the array and add a new string for each font, making the string the file’s full name including an extension.

Xcode Screenshot

You’re all set up now to use the font. That would be great if you knew which font it was! Here is a great little snippet for looping through all the fonts loaded into the system. Scan through the list and find your font.

Objective-C:

// Get all the fonts on the system
NSArray *familyNames = [UIFont familyNames];
for( NSString *familyName in familyNames ){
	printf( "Family: %s \n", [familyName UTF8String] );
	NSArray *fontNames = [UIFont fontNamesForFamilyName:familyName];
	for( NSString *fontName in fontNames ){
		printf( "\tFont: %s \n", [fontName UTF8String] );
	}
}

Swift:


// Get all the fonts on the system
UIFont.familyNames.forEach { familyName in
    print("Family: \(familyName)")
    UIFont.fontNames(forFamilyName: familyName).forEach { fontName in
        print("\tFont: \(fontName)")
    }
}

To use your font now, just use the standard UIFont constructor…

Objective-C:

self.titleLabel.font = [UIFont fontWithName:@"Inkpen Medium" size:31.0];

Swift:


self.titleLabel.font = UIFont(name: "Inkpen Medium", size: 31.0)

Some points to note: –

  • You can also use the font inside UIWebViews.
  • Interface Builder for XCode 3.2 has a bug that won’t let you choose the font. You have to do it in code.
  • Loading in too many fonts will slow your loading time down and will hurt your users’ eyes.

Re-ordering Core Data Objects on iOS4

The Core Data framework on the iPhone is incredibly powerful. It’s also incredibly efficient and part of that is because a collection of objects only have the order that you implicitly give them. For example you typically might give an Event object a timestamp and when you pull out all the events you might sort on that timestamp.

The NSFetchedResultsController is the main power house when dealing with such a scenario and is great for the master part of a master/detail data relationship. Its main purpose is to manage the results returned from a fetch request similar to the above and provide data for a UITableView via delegate methods. It reacts on the model level so if you delete an Event object, the NSFetchedResultsController informs its delegate and so updates the UITableView automatically. It’s very clever indeed!

As I found out earlier yesterday, the problem comes when you want to re-order the objects in a user-defined way. Instead of sorting on a timestamp, I wanted the user to be able to specify that one object should occur before the other… I’m working on an app that lets you place waypoints down on a map. Timestamps in waypoints aren’t much use. It’s much more critical that they have a specific order.

After some Googling I came across a useful article on CocoaIsMyGirlfriend. This helped me 90% of the way but I had problems when re-ordering. When you re-order the objects, the UITableView would move cells about seemingly at random. This is because NSFetchedResultsController is model-driven. When you re-order something using the tableview methods the view is already correct (because you’ve dragged and dropped the cell there – it’s a user-driven change) and so when the delegate detects your index changes, it walks all over your view believing the cells to be in their original position. The trick is to ‘disable’ the UI updates with a boolean in your delegate methods. Set the boolean just before your re-indexing and unset it afterwards.

For an example, see this stack overflow link on re-ordering.

Also have a look at what the Apple docs say on user-driven updates on the NSFetchedResultsController.

Pub Darts now with Instructions!

Pub Darts iconWhen I first launched Pub Darts last March, I got many great positive messages from people who love throwing darts at their boss’s picture! I also got much negative feedback from people who found the throwing mechanism difficult or not as intuitive as I thought it was. Therefore adding instructions to version 1.1 was very important to avoiding those 1 star reviews!

However due to work commitments it has had to sit on the back-burner but with the recent release of the iPhone 4, I couldn’t help but update Pub Darts with gorgeous high resolution artwork. I also managed to add in some instructions, make a new icon, fix a few bugs, allow games to save themselves when you quit and completely redo the shadows to be more ‘iPhone-like’. This free update can be grabbed immediately from your iPhone by updating in the App Store application.

More updates are coming soon. Feel free to suggest some features you’d like to see. If you’ve yet to experience Pub Darts on your iPhone, grab it for free now.

Pub Darts Screenshot Pub Darts Screenshot

Take Audi iPad Magazine for a Drive

It’s such a good feeling when something you’ve worked so hard on gets unleashed onto the App Store. It’s even more of a great feeling when you find out your app has already broken into the Top 50 chart of most-downloaded free apps. Achieving more than 15,000 downloads in the first two weeks, I’m immensely proud to have been the lead developer of Audi Magazine for iPad. Download it for free now!

As a team, we spent considerable time making sure the rotating mechanism worked just right and making sure the app loads in less than half a second. I’m looking forward to starting on the next issue soon!