Non-rectangular buttons for the iPhone

I haven’t checked the iPhone 4.0 sdk yet, but last time I looked you could not do non-rectangular buttons or UIViews with the UIKit.

This becomes a problem when you do UI’s that overlap clickable areas of non-rectangular shape. You see this a lot in games.

In order to get this working I had to add the following code to my UIImageView derived class -


- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
	if ([super pointInside:point withEvent:event])
	{
		uint components, x, y;
		uint imgWide, imgHigh;      // Real image size
		uint rowBytes, rowPixels;   // Image size padded by CGImage
		CGBitmapInfo info;            // CGImage component layout info
		CGColorSpaceModel colormodel; // CGImage colormodel (RGB, CMYK, paletted, etc)
		uint * pixels = NULL;

		CGImageRef image = self.image.CGImage;

		// Parse CGImage info
		info       = CGImageGetBitmapInfo(image);		// CGImage may return pixels in RGBA, BGRA, or ARGB order
		colormodel = CGColorSpaceGetModel(CGImageGetColorSpace(image));
		size_t bpp = CGImageGetBitsPerPixel(image);
		if (bpp < 8 || bpp > 32 || (colormodel != kCGColorSpaceModelMonochrome && colormodel != kCGColorSpaceModelRGB))
		{
			// This loader does not support all possible CGImage types, such as paletted images
			CGImageRelease(image);
			return false;
		}
		components = bpp>>3;
		rowBytes   = CGImageGetBytesPerRow(image);	// CGImage may pad rows
		rowPixels  = rowBytes / components;
		imgWide    = CGImageGetWidth(image);
		imgHigh    = CGImageGetHeight(image);

		// Get a pointer to the uncompressed image data.
		//
		// This allows access to the original (possibly unpremultiplied) data, but any manipulation
		// (such as scaling) has to be done manually. Contrast this with drawing the image
		// into a CGBitmapContext, which allows scaling, but always forces premultiplication.
		CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(image));
		pixels = (uint *)CFDataGetBytePtr(data);

		uint32_t *p = (uint32_t *)pixels;
		int i, num = imgWide * imgHigh;

		if ((info & kCGBitmapByteOrderMask) != kCGBitmapByteOrder32Host)
		{
			// Convert from ARGB to BGRA
			for (i = 0; i < num; i++)
				p[i] = (p[i] << 24) | ((p[i] & 0xFF00) << 8) | ((p[i] >> 8) & 0xFF00) | (p[i] >> 24);
		}

				// check pixel
		uint32_t alpha = p[(int)((point.y*rowPixels)+point	.x)]; // << 24;
		CFRelease(data);

		return alpha;
	}

	return false;
}

"Non-rectangular buttons for the iPhone" was published on May 21st, 2010 and is listed in Mobile Development.

Follow comments via the RSS Feed | Leave a comment | Trackback URL

Leave Your Comment