4

how can i create a UIButton in shape of the image given.

i am able to create something close to it,but the image seems to be not fitting in the button. my requirement is the image given below.i.e;semicircle

the code i used to create the button is given below.

what changes should i make on the following image to get this button. ps-add subview done in another class..

btnStartGame  =[UIButton buttonWithType:UIButtonTypeCustom];
[btnStartGame setFrame:CGRectMake(60, 200, 200, 200)];

btnStartGame.titleLabel.font=[UIFont fontWithName:@"Helvetica-Bold" size:30];
[btnStartGame setImage:
[UIImage imageNamed:@"Draw button.png"]  forState:UIControlStateNormal];

btnStartGame.titleLabel.textColor=[UIColor redColor];
btnStartGame.clipsToBounds = YES;
btnStartGame.layer.cornerRadius = 50;//half of the width
btnStartGame.layer.borderColor=[UIColor redColor].CGColor;
btnStartGame.layer.borderWidth=2.0f;

btnStartGame.tag=20;
btnStartGame.highlighted=NO;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
Suraj K Thomas
  • 5,773
  • 4
  • 52
  • 64
  • 1
    i forgot to mention the most important thing ,click on button should not exceed outside the image...strictly inside the image.. – Suraj K Thomas Feb 07 '13 at 11:27
  • 1
    its nothing but start screen of a small game which i am developing.i have to go to main page after clicking this button.but when I'm integrating graphics for this,i am having this problem,i can create a similar button but now the problem is if I'm clicking parts outside image of button (which is supposed to be the button)it is taking a click.pls help – Suraj K Thomas Feb 07 '13 at 12:03

2 Answers2

2

There is a really great tutorial here with downloadable source code:

http://iphonedevelopment.blogspot.co.uk/2010/03/irregularly-shaped-uibuttons.html

In essence you need to create a category on UIImage, which checks whether the point you have touched is transparent image or not. This means you can use it to check hit tests on irregular shapes.

You then subclass UIButton and over-ride the hitTest:withEvent:

Hope this helps

Tim
  • 3,434
  • 1
  • 14
  • 13
  • 1
    great tutorial dude...it was perfectly working.i copied 2 classes OBShapedButton and UIImage+ColorAtPixel from the program,imported them to my program and made button to be instance of 'OBShapedButton class'.it was detecting only the image and the problem i mentioned was not happening.i also commented the following lines in the code i have given above. – Suraj K Thomas Feb 07 '13 at 13:35
  • btnStartGame.clipsToBounds = YES; btnStartGame.layer.cornerRadius = 50;//half of the width btnStartGame.layer.borderColor=[UIColor redColor].CGColor; btnStartGame.layer.borderWidth=2.0f; ANYBODY CAN CREATE BUTTONS OF ANY SHAPE USING THIS METHOD.FOLLOW TUTORIAL AND DO LIKE WHAT I HAVE DONE.ITS SO SIMPLE AS THAT. – Suraj K Thomas Feb 07 '13 at 13:37
1

Although the solution by Jeff Lamarche linked by the other answer works fine, it uses a lot of memory, and/or does a lot of work:

  • If you create NSData once in the initializer, you end up holding a relatively large block of memory for the lifetime of each button
  • If you make it transient, the way it is done in the answer, then you end up converting the entire image each time you hit test your button - processing thousands of pixels and throwing away the result after fetching a single byte!

It turns out that you can do this much more efficiently, both in terms of memory use and CPU consumption, by following the approach outlined in this answer.

Subclass UIButton, and override its pointInside:withEvent: method like this:

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (![super pointInside:point withEvent:event]) {
        return NO;
    }
    unsigned char pixel[1] = { 0 };
    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 1, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
    UIGraphicsPushContext(context);
    UIImage *image = [self backgroundImageForState:UIControlStateNormal] ;
    [image drawAtPoint:CGPointMake(-point.x, -point.y)];
    UIGraphicsPopContext();
    CGContextRelease(context);
    return pixel[0] != 0;
}

The code above takes alpha from the background image of the button. If your button uses another image, change the line that initializes image variable above.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523