Ole Begemann: iOS Development

iOS SDK, Cocoa and Objective-C

OBShapedButton: Non-rectangular buttons on the iPhone

with 6 comments

UIButton has always been capable of displaying buttons with arbitrary non-rectangular shapes. All you have to do is use PNG images with alpha channels to define the transparent parts of the bounds rectangle.

While a button’s shape may be arbitrary, UIButton always responds to touches within its entire bounds, however. This could cause problems and confusion for the users, especially when multiple non-rectangular buttons are placed close together so that their frames overlap.

OBShapedButton is a replacement for UIButton that solves this issue. Instances of OBShapedButton only respond to touches where the button image is non-transparent. Here’s how to use it:

  • Get the code from GitHub.
  • Add OBShapedButton.h, OBShapedButton.m, UIImage+ColorAtPixel.h, and UIImage+ColorAtPixel.m to your Xcode project.
  • Design your UI in Interface Builder with UIButtons as usual. Set the Button type to Custom and provide transparent PNG images for the different control states as needed.
  • In the Identity Inspector in Interface Builder, set the Class of the button to OBShapedButton.

That’s it! Build and run the enclosed demo project to check it out. I am releasing this under the MIT license.

Written by Ole Begemann

October 17th, 2009 at 6:53 pm

Posted in Uncategorized

6 Responses to 'OBShapedButton: Non-rectangular buttons on the iPhone'

Subscribe to comments with RSS or TrackBack to 'OBShapedButton: Non-rectangular buttons on the iPhone'.

  1. [...] Ole Begemann has also created a custom button class which he talks about here: OBShapedButton: Non-rectangular buttons on the iPhone. [...]

  2. Very, very helpful – many thanks!

    Iain Barclay

    20 May 10 at 1:58 pm

  3. you are the man, dog.

    roboris

    21 Jun 10 at 1:38 pm

  4. [...] OBShapedButton: Non-rectangular buttons on the iPhone [...]

  5. To get this to work I had to flip the context vertically, otherwise the context you’re using is upside down.

    I added this at line 81:
    // Flip context
    CGContextTranslateCTM(context, 0, height);
    CGContextScaleCTM(context, 1.0, -1.0);

    I think you may have never noticed it because your shapes are diamond shaped so it doesn’t matter if they’re flipped. I was using a PNG of a duck…and was having all sorts of problems!

    Let me know if I’m mistaken.

    Steven Baughman

    16 Jul 10 at 6:42 pm

  6. Hi,

    Just played with your class and found out that it’s not working correctly on iPhone 4 if you have higher resolution of the image

    Small correction in colorAtPixel fixes the issue:
    /*On retina display we should use frame rect not the actuall image*/
    NSUInteger width = self.size.width;
    NSUInteger height = self.size.height;

    Poopi

    7 Aug 10 at 7:53 pm

Leave a Reply