iPhone button with non-rectangle shape? - iphone

How can I get a non-rectangular shaped button?
For example I do have a PNG image with alpha transparency.
How can I set the shape of a button to this image without the transparent color.

Like the others say you should have a reasonable surface for registering touch events, but I'm sure you know that and have your reasons so I'll just tell you how I did it:
I needed to do this not so long ago and what I did is what Sixten Otto just suggested. There are some hints in my original question ("UPDATE" section) for getting the alpha value for your image at a certain point:
How to create a transparent window with non-rectangular buttons?
Edit: I suggest subclassing UIControl in the example below but if you don't need any special behavior on your button apart from the "non-rectangleness" of it then just subclassing a borderless UIButton set up with your PNG will do the job and require less work. You have more control on the control's behavior by subclassing UIControl and doing it the "hard way" though.
I would suggest that you subclass UIControl and override the touch event methods, then check for alpha under the tapped point and not handle the event if alpha == 0. For drawing you override drawRect: and use the NSImage's drawInRect:fromRec:operation:fraction: method in there to draw your image in the control's frame.
First you need to load the image and get a bitmap representation of it:
buttonImage = [NSImage imageNamed:#"myButtonImage"];
buttonImageRep = [[buttonImage representations] objectAtIndex:0];
Then you can draw it to the control's view: (where stateImage is a pointer to the image that must be drawn depending on if the button is pressed or not)
- (void)drawRect:(NSRect)aRect {
[stateImage drawInRect:[self bounds] fromRect:NSMakeRect(0.0,0.0,[buttonImage size].width,[buttonImage size].height)
operation:NSCompositeSourceOver fraction:1.0];
}
At this point you have drawn your button with your png image. You can override the touch event methods and handle the event if the alpha is not 0:
NSColor *colorUnderMouse = [buttonImageRep colorAtX:mouse.x y:mouse.y];
float alpha = [colorUnderMouse alphaComponent];
That's what I did and it works wonderfully. Hope this helps!
N.B: My example is for the Mac but it should also work on the iPhone, maybe with some slight modifications.

It sounds like you are looking to have the clickable area of the button exactly match the PNG you are using.
If that is what you are looking for, I would firstly say to not do that. The iPhone is pressed using a finger, which generally doesn't have the accuracy to distinguish such a small region.
However if you are stuck on the idea, then the solution is to not use buttons at all, instead handle the click in a parent frame and manually interpret the X/Y value of the click to determine if it is in some bounding region (In the case of a rounded edge button, would likely consist of oring the result of checking 4 circles and 2 rectangles)
Edit:
Realizing part of your original question, I noticed you mentioned you wanted to handle the function automatically based on the Alpha channel. While I would recommend my method of bounding regions, you could in theory accomplish this by sampling the PNG to test the Alpha channel at a value offset by the origin of the button. Potentially even doing this in a normal button's click event.

Rectangular buttons are a button type, you can use the custom button type and assign an image to get rid of the rectangular edges of the button...heres a reference to button types http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/doc/c_ref/UIButtonType and to UIButton http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html

As Guvante says, it's really not a good idea to rely on precision touches. Apple, for instance, recommends that controls be at least 44px across.
I'd recommend using a UIButton of type UIButtonTypeCustom, set the button's image to your PNG, and register for touch events (see here for more on event handling). Then, in your action method, you can get the coordinates of the touch out of the event, and test those coordinates against the alpha of your image to see whether you should treat it as a "real" touch or not.

Another option could be to split your button up into multiple, rectangular parts.

#Form right about using 'drawRect' to implement custom shape for button.
But better method to exam touch inside or not inside button is using of
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
You can create your button transparent for touches in some parts.
If you can't use custom image for button (for example if you draw text on the button) you can use new method to draw subviews hierarchy into a image:
- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates;

Related

How can i make a custom UIButton so that it has irregular curves like a rock,stone,tree ...etc?

I wanna to make a button so that it has the shape of a stone/ rocket (i.e. irregular shape not a rectangle, square ... etc)
, i wanna to make it also highlighted/bordered with the same shape , i tried a UIButtonTypeCustom but it did not give me what i want .. so anyone has any help or idea, don't be skimpy.
Thanks in advance.
Use UIButtonTypeCustom but also add your custom assets for the look of the button.
Typically you will set the background image of the UIButton to some image you want (your rock, rocket, etc) for each state of the button (Normal, Highlighted, Disabled…).
Simply add the images in your Xcode project, then set the background image for each state of your UIButton directly in your XIB (using the Object Inspector panel on the right), or via code using the setBackgroundImage:forState: method.

Rectangular Selection like in Windows Desktop

I'm making a Schedule App for Cocoa Touch and I need to be able to select a time interval just by touching the screen. I mean, the user must be able to select with its fingers a time interval within the "ScheduleView" and then Add an event.
I was thinking of making some kind of rectangular selection, similar to the one that everyone can do in Windows Desktop, but i don't know how to detect multiple touches, neither how to draw the selection rectangle. Can anyone help me?
P.S: The "ScheduleView" it's a UIView, not a UITableView
You'll need to add a UIGestureRecognizer to your view. You can detect touches as a delegate, and this case will probably do best with a UIPanGestureRecognizer. You'll set the delegate to be yourself and draw the box within -(void)panGestureMoveAround:(UIPanGestureRecognizer *)gesture Here is a tutorial.
To draw the box, you could manually draw into the view but it may be easier to reshape a UIView on top and manipulate its border width and color like this SO question.

round image button VS square controller

I have a custom button with a round image.
The problem is that the controller is square by default so whenever i click on the corners of the image, the button responds calling the associated method, when in reality he shouldn´t because there is no image on the corners, so the button shouldn´t respond.
Anyone knows a work around this bug?
One way to handle this is to reduce the size of the button. It'll still be a rectangle (or square) though. More involved way would be to implement - (UIView *) hitTest: (CGPoint) pt withEvent: (UIEvent *) event & handle which area of the button was clicked & if its not in the circle you defined ignore that touch event.
But if you ask me, let it be the way it is. In touch, people are rarely that accurate (compared to a mouse click). So the rectangle button provides more area for the user to tap on a button even if he is slightly off the mark.
You can't solve this with UIControl settings. You'll have to do custom hit detection and determine if the image is under the tap. You can do this using UITapGestureRecognizer.

How to configure UIButton to use showsTouchWhenHighlighted?

I have a UIButton that's 90x90 in size and I would like it to glow when tapped. Using showsTouchWhenHighlighted will make it glow but it's glowing out of the center of the button and for a small radius only. This might work well for a small button like the info button, but for my button size, it's not. Is there anything I can do to make it glow from the outer perimeter of the button before I resort to designing a highlighted state?
I can think of 2 ways to do what you want:
Use different highlighted background image for your button's highlighted state,
Use CoreGraphics to draw the glow effect in your button's IBAction (touchDown is a decent place).
This is assuming you want some kind of custom glow effect of course - UIButtons already naturally have a highlighted effect when touched.

Which IPhone control would be better?

I have a situation in which user can single tap a control, which show random images, to peek under it, double tap to mark it, or drag it to a box where it snaps to the box if more than half of its body is inside box.
I was using UIbuttons (with background image) before and have done the single/double tap thing for them, how to do the drag and snap to a box based on the cross-section of covered area by box?
What if i use uiimage? i know dragging a uiimage object is possible, is double/single tap is also possible for uiimage?
Yes, it's possible with UIImageView - you can implement the various touch methods just as easily on any UIView descendant, which includes UIImageView.