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) <<
| ((p[i] >>
& 0xFF00) | (p[i] >> 24);
}
// check pixel
uint32_t alpha = p[(int)((point.y*rowPixels)+point .x)]; // << 24;
CFRelease(data);
return alpha;
}
return false;
}