Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton inside UIView doesn't respond to touch events

I've put a UIButton inside a custom UIView and the button is not receiving any touch events (it doesn't get into the highlighted state, so my problem is not about being unable to wire up a touch inside up handler). I've tried both putting it into the XIB in Interface Builder, and also tried programatically adding the UIButton into the UIView seperately, both ended with no luck. All my views are inside a UIScrollView, so I first though UIScrollView may be blocking them, so I've also added a button programatically exactly the same way I add my custom view into UIScrollView, and the button worked, elimination the possibility of UIScrollView could be the cause. My View's hiearchy is like this:

ss

The button is over the image view, and the front layer isn't occupying my button completely, so there's no reason for me not be physically interacting with the button. At my custom view's code side, I'm creating my view as such:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        UIView *sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0];
        [self addSubview:sub];
        [sub setUserInteractionEnabled:YES];
        [self setUserInteractionEnabled:YES];
        CALayer *layer = sub.layer;
        layer.masksToBounds = YES;
        layer.borderWidth = 5.0;
        layer.borderColor = [UIColor whiteColor].CGColor;
        layer.cornerRadius = 30.0;
        /*layer.shadowOffset = CGSizeZero;
        layer.shadowRadius = 20.0;
        layer.shadowColor = [[UIColor blackColor] CGColor];
        layer.shadowOpacity = 0.8;
        */
    }
    return self;
}

I've tried all combinations of setUserInteractionsEnabled, and had no luck. (Yes, also set them to checked in Interface Builder too). I've also read in another question with a similar problem that I should try overriding 'canBecomeFirstResponder' to return 'YES' and I've also done that too. But the problem persists, I can't click the button. I've not given any special properties, settings to the button, it's just a regular one. My other objects in the view (labels below, image view behind the button etc.) are working properly without problems. What could be possibly wrong here?

Thanks,

Can.

UPDATE: Here is a quick reproduction of the problem: https://dl.dropbox.com/u/79632924/Test.zip Try to run and click the button.

like image 731
Can Poyrazoğlu Avatar asked Nov 25 '12 00:11

Can Poyrazoğlu


4 Answers

Looking at the test project, I believe your problem in the way you create TestView, you do not specify the frame for it, so basically the parent view is 0 size, and the subviews you see from XIB extending out of the parent view and thus do not get anything in responder chain.

You should either specify the frame when creating TestView, or adjust the frame after loading XIB file.

like image 116
Dmitry Shevchenko Avatar answered Nov 07 '22 07:11

Dmitry Shevchenko


I have had this problem as well. The cause for me was that the UIButton superview frame was of height 0, so I believe that even though a touch was happening, it was not being passed down to the button.

After making sure that the button's superview took a larger rectangle as a frame the button actions worked.

The root cause for this problem on my side was a faulty auto layout implementation (I forgot to set the height constraint for the button's superview).

like image 42
Alex Avatar answered Nov 07 '22 08:11

Alex


I've found the solution. I was initializing my custom view as:

MyView *view = [[MyView alloc] init];

I've initialized it instead with a frame of my view's size, and it started responding to events:

CGRect rect = CGRectMake(0,0,width,height);
MyView *view = [[MyView alloc] initWithFrame:rect];
like image 2
Can Poyrazoğlu Avatar answered Nov 07 '22 09:11

Can Poyrazoğlu


Storyboard Solution

Just for anyone wanting a solution to this when using storyboards and constraints.

Add a constraint between the superview (containing the button) and the UIButton with an equal heights constraint.

In my case, I had selected embed UIButton in a UIView with no inset on the storyboard. Adding the additional height constraint between the UIButton and the superview allowed the UIButton to respond to touches.

You can confirm the issue by starting the View Debugger and visually confirm that the superview of the UIButton is not selectable.

(Xcode 11, *- Should also work in earlier versions)

like image 1
Tommie C. Avatar answered Nov 07 '22 09:11

Tommie C.