views:

741

answers:

2

I want to be able to create a UIButton with an oversized responsive area. I know that one way to do that is to override the hitTest method in a subclass, but how do I instantiate my custom button object in the first place?

[OversizedButton buttonWithType: UIButtonTypeDetailDisclosure];

doesn't work out of the box because buttonWithType returns a UIButton, not an OversizedButton.

So it seems like I need to override the buttonWithType method as well. Does anyone know how to do this?

@implementation OversizedButton

+ (id)buttonWithType:(UIButtonType)buttonType
{
   // Construct and return an OversizedButton rather than a UIButton
   // Needs to handle special types such as UIButtonTypeDetailDisclosure
   // I NEED TO KNOW HOW TO DO THIS PART
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{
   // Return results if touch event was in oversized region
   // I ALREADY KNOW HOW TO DO THIS PART
}

@end

Alternatively, maybe I could create the button using alloc/initWithFrame. But the buttonType property is readonly, so how do you create the custom button types?

Note: I know there are other ways to do this, such as having an invisible button behind the visible one. I don't care for that approach and would prefer to avoid it. Any help on the approach described above would be very helpful. Thanks

A: 

The buttonType property is not used anywhere in UIKit, and in your code you could always check -isKindOfClass:, so overwriting +buttonWithType: for this property is rather pointless IMO. Just use

return [[[OversizedButton alloc] initWithFrame:...] autorelease];

(You can override the button type with the undocumented method _setButtonType:.)

KennyTM
Are you seriously suggesting that I use an undocumented method in a commercial application that would require Apple approval?
Amagrammer
@Ama: I suggest you don't bother with the `buttonType` property. But if you must, the only way to change it is via undocumented methods.
KennyTM
Well, I need to display UIButtonTypeDetailDisclosure buttons, so "not bothering" won't work. Should I assume that to your knowledge there is no way to override the buttonWithType method? Thanks
Amagrammer
+2  A: 

UIButton buttonWithType: returns a UIButton or a UIRoundedRectButton, depending on the value of the type parameter.

As UIButton doesn't provide an initWithType: method, I believe it would be dangerous to try and override buttonWithType:.

I suggest you subclass UIControl instead. You can then add a button as a subview to your control, and intercept hitTest:withEvent:.

Can Berk Güder
I'm experimenting with that because it does appear the other is not practical. It seems terribly inelegant though. Thanks.
Amagrammer