Mar 25, 2010
When you look at the Contacts.app you see that Apple somehow manages to change the size of cells in UITableViews of grouped styling.
If you search around on the internet most of the solutions getting such a look revolve around making your own UIView and adding this as headerView to a section. Now if you want the cell on the right side to still behave like a cell is expected to behave then you have lots of work ahead of you. So I consulted the twitterverse and here props have to go to Jason Terhorst who hit the bull’s eye:
If I recall correctly from Apple’s example code, they just clear the background, and redraw that rounded rect at new size. It’s been a while since I did this, but I think I swapped in my own custom backgroundView.
I researched and experimented for a day to get it perfect. What follows is a description of how to pull off this magic trick, so you can do so too. The end result will look like this:
(Heart Icon by DryIcons)
Mar 23, 2010
At times you may find that you need a control that has not yet been provided for you. In my case I needed a star rating control for iWoman. Ladies will be able to star their love encounters. And the way how such a thing is done nowadays is via selecting between 0 and 5 stars. (If you now ask me to rig it such that your girl can only rate you with 5 stars, then I’ll bitch-slap you)
So I decided to make a UIView that would take UIImages for empty, half-full and full stars. Also I wanted to have some customizability like different numbers of stars and to be able to turn half-full stars on and off. That’s where I created multiple properties so that these values can be set from outside the instance. The steps are always: instance variable (“IVAR”), @property, @synthesize and if the property is a retained object then a line in dealloc.
I made this YouTube video to give you a demonstration and guided tour of DTStarRatingView.
Mar 20, 2010
I’m adding note taking to iWoman 2.0 and so I was thinking which metaphor would be one that users would understand and like. So I decided to mimic the look and feel of the built-in Notes app.
There where quite a few interesting things I had to learn and figure out and in this article I am going to share them with you. These are techniques that you can use in many other scenarios besides of making your own Notes view controller.
I was clear from the start that I needed to use a UITextView for the editing itself. Notes.app has several specialities that we have to figure out if we want to capture the look.
- Font is Marker Felt Thin, Size 19.
- each line sits on top of a grayish blue horizontal line
- the text view has a padding at all sides, something that the standard UITextView does not give us
- There is padding at the top, but still the text goes up to the corner
- the horizontal lines move together with the text and never end towards the bottom
- two static vertical brown lines line up with markings at the top and the bottom
- the body of the notes is not just a yellow gradient, but has some structure and speckles
- scrolled text disappears behind the images for the top and bottom edge
- The text view needs to be dynamically resized when the keyboard appears or disappears to prevent hiding of text.
Those where the challenges, in this YouTube video you see my solution and an overview of how I achieved it. More in-depth reasoning you find below.
Mar 14, 2010
Being present longer than iPhone OS exists on the Mac platform NSPredicate was only introduced to us iPhone developers in Version 3.0 of the SDK. They have multiple interesting uses, some of which I am going to explore in this article.
You will see how you can filter an array of dictionaries, learn that the same also works for your own custom classes. Then we’ll see how to replace convoluted IF trees with simple predicates. We’ll explore how to use predicates to filter entries of a table view and finally peek into the inner workings of predicates.
Being simple and powerful at the same time it took me 3 hours to write this article. I hope you don’t give up halfway through it, because I promise it will be a great addition to your skillset as iPhone developer.
Mar 07, 2010
The first thing to learn when starting to persist data onto the iPhones solid state drive is that all apps have their own sandbox. Contrary to other operating systems where you have a shared documents folder, you have several directories for each individual apps. Now on the iPhone these sandbox directories all get a GUID in their name, so you have no way to hardcode or guess the real path they will end up on.
Luckily there is a method of getting the path for those directory, which I wrote about about a year ago: Getting Standard Paths. Today I will elaborate a bit on what I learned since then, it turns out that this is only half the story and as intermediate programmer you will want to use the correct kind of folder for each task.
Feb 28, 2010
Yesterday I sent my first app off to Apple containing an InAppPurchase (IAP). It’s a free app that gives the user an option to pay a dollar for a premium features. That’s what they call Freemium these days. Free to try, premium to get some more.
The possibility for Freemium was only introduced in October 2009 when Apple finally gave in to developer’s wish to be able to do away with those dreaded Lite versions which have a very low conversion rate (about 1%) anyway. Until that time IAPs where only available for paid apps.
After developing on the premium content for about two weeks I hit my first roadblock. You apparently cannot configure an app id for use in a provisioning profile it it is already configured on another developer’s account.
If you are looking for a full walkthrough, this is not the article to provide that. Troy Brant has the most complete IAP Walkthrough on his blog. Instead this is a summary of my mental notes.
Feb 19, 2010
One day of the week I hope to do something that’s not really business oriented, I call it my “Friday-Project”. This title comes from my time in IT where you would generally avoid do any major changes to the systems you are maintaining on Fridays because nobody likes to work on fixing these on the following weekend. So Friday is a great day to just experiment, prototype or dream. At Google they are supposedly giving their employees 20% of their working time for such projects, so I am dedicating as much time to playful exploration as well.
Today I want to explore and hopefully finish some code to upload an image to TwitPic. So the first step is to have a look at their API documentation which is not very pretty, but at least it’s complete. There we see that we want to implement the uploadAndPost function.
Use this method to upload an image to TwitPic and to send it as a status update to Twitter.
Fields to post in post data should be formatted as multipart/form-data:
– media (required) – Binary image data
– username (required) – Twitter username
– password (required) – Twitter password
– message (optional) – Message to post to twitter. The URL of the image is automatically added.
For this we need to construct an HTTP POST request to the URL http://twitpic.com/api/uploadAndPost and construct a multipart body with binary image data, Twitter username, password and an optional message. The response will be XML giving us the URL we can use to link to the picture.
Having the parameters intermixed makes it a bit harder especially if you have never constructed a multipart body before. The easiest method of image uploading is if you can specify parameters in the URL, but the designer of this API thought it smarter to have it in the body. But don’t worry, we’ll get this figured out as well.
Feb 18, 2010
For my current project DTAboutViewController I need to be able to specify tokens in my strings that would be replaced by information about the app at runtime. Of specific interest are CFBundleDisplayName and CFBundleVersion which are both in info.plist. Usually you could hard-code these into your app strings or maybe do a global #define, but for my component I wanted to have the most flexibility with the least amount of work in subsequent project that would use that.
So I put together a category extension for NSString which also shows off how to use NSScanner to find tokens and replace them with values from your info dictionary.
@interface NSString (Helpers)
- (NSString *) stringBySubstitutingInfoTokens;
@implementation NSString (Helpers)
- (NSString *) stringBySubstitutingInfoTokens
NSMutableString *tmpString = [NSMutableString stringWithString:self];
NSScanner *scanner = [NSScanner scannerWithString:self];
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
while (![scanner isAtEnd])
if ([scanner scanString:@"$" intoString:nil])
if ([scanner scanCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:&tokenName])
id value = [infoDict objectForKey:tokenName];
if (value && [value isKindOfClass:[NSString class]])
[tmpString replaceOccurrencesOfString:[@"$" stringByAppendingString:tokenName] withString:value options:NSLiteralSearch range:NSMakeRange(0, [tmpString length])];
[scanner scanUpToString:@"$" intoString:nil];
return [NSString stringWithString:tmpString];
The code works by skipping all characters until it encounters a $, which will be our token identifier. From this position the name of the token is until the first non-alphanumberic character, like a space or period. Then it tries to get a value from the bundle’s info dictionary. If it succeeds the token is replaced in a temporary string, if not it is left unchanged.
Note how I am passing nil into scan functions if I am only interested in skipping characters. If I am interested in the scanned result, then I am passing the address of a pointer to an NSString, that’s the reason for the &tokenName. The scan method creates an autoreleased copy of the scanned string and puts the pointer to this string into the parameter the address of which you have passed. That’s unusual in objective-C and seen more often in pure C code, so be aware of that.
Now with this code I gain a very useful way of displaying copyright information as the section footer of my settings table.
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
return [@"© 2010 Drobnik.com. $CFBundleDisplayName $CFBundleVersion" stringBySubstitutingInfoTokens];
This will look like this, the app’s bundle display name is “About” and the version string is “1.0”.
With this method it’s even thinkable to put your own information into info.plist. Like for example the ID of your app which you would use for a direct link to the review page. Some people complain that Cocoa does not have regular expression support, but actually if you know how to use NSScanner properly you can do even more with it than trying to piece together working regexps.
Feb 13, 2010
I am working on the ultimate “About Page” component at the moment. And of course this won’t be complete without a button to follow the developer on Twitter. Tapbots is one company that has the best role model for modeling this. They have this little button here at the bottom of their about page:
There is something amazing that happened when I tapped on this “Follow us on Twitter” button: it opened up the tapbots user right in Tweetie 2! I was astonished at first, but then it dawned on me that on the iPhone you can have your app respond to a custom URL scheme and obviously some Twitter clients support going to the user’s profile page. I have only Tweetie 2 installed and incidently this supports just that.