Reputation: 225
I have a UIButton2 that is added on to UIButton1:
The action @selector only gets called where UIButton2 intersects UIButton1 (the "b"). So, a tap in the "a" or "c" area, the action method (addDockButtonTouchedDown) does NOT get called, but it does when you tap in the "b" section. Here's some code:
// button1 is created elsewhere in the code and is a subclass of UIButton for UI layout (has a footer label and title label set). nothing fancy going on. button1 userInteractionEnabled is set to yes
// button2 is below...
NSString *dockPath = [[NSBundle mainBundle] pathForResource:@"AddToMyDock" ofType:@"png"];
UIImage *dockImage = [UIImage imageWithContentsOfFile:dockPath];
CGRect rect = CGRectMake(-20.0f, -10.0f + dockImage.size.height+1, dockImage.size.width, dockImage.size.height);
UIButton *button2 = [[UIButton alloc] initWithFrame:rect];
button2.userInteractionEnabled = YES;
button2.exclusiveTouch = YES;
[button2 setBackgroundImage:dockImage forState:UIControlStateNormal];
[button2 addTarget:self action:@selector(addDockButtonTouchedDown:)
forControlEvents:UIControlEventTouchDown];
[button1 addSubview:button2];
Any ideas why this is happening and how to fix it??? Please don't suggest to simply make button1 bigger.
Upvotes: 0
Views: 165
Reputation: 1858
It not works on "a" and "c" regions because the hit test for the touch event fails there when called for button1. You should subclass UIButton for button1 and override the hit test with something like this:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if(CGRectContainsPoint(self.childButton.frame, point)) {
return [self.childButton hitTest:[self convertPoint:point toView:self.childButton] withEvent:event];
}
return [super hitTest:point withEvent:event];
}
Note: childButton is button2 in your example.
Note2: I think that however this should work, the ugliness of this is a sign of a design problem, but that's your business.
Upvotes: 0
Reputation: 16946
First of all, adding a button as a subview of another button isn't really common design and I would avoid doing that. Simply create a container UIView that holds both buttons.
The problem you're seeing is because while your button may be displayed beyond the bounds of its superview (the other button), actions on the outside of button1's bounds won't be registered. The only reason you can see button2, is because clipsToBounds
is set to NO
on button1, which allows its subviews to be drawn outside of its bounds.
So, the only way to make your current solution work is indeed by making button1 bigger. However, the better option would be to create superview that's big enough to hold both buttons, and add both buttons to it.
Upvotes: 2