46

I've made plenty of buttons and I can't figure out why this one won't work.

My hierarchy is set up like this:

View -> Scroll View -> Subview -> Button

There's a lot of other items in this subview and every one of them works when touched. In the interface builder I can see that the "Touch Up Inside" event is bound to my method

- (IBAction)favoritesButtonDepressed:(id)sender 

However, when I click the button, that method never executes and my breakpoint is subsequently never hit.

I noticed that even when I hold down my press on the button, the label doesn't change color (even though shows touch on highlight is enabled), but yet my other button on the view does.

User Interaction is enabled on the button as well as everything up the hierarchy.

In order for my items in the sub view to receive touch events, I made my scroll view look like the 4th answer in this post.

shim
  • 9,289
  • 12
  • 69
  • 108
Architekt
  • 2,141
  • 1
  • 22
  • 27

18 Answers18

75

Aha, I got it. It turns out the subview which contained the button (along with the other controls) had a height of 740 and the button was at a Y of 781. Moving the button up fixed the issue. Since everything was displaying correctly, I didn't think to check the subview's height.

Architekt
  • 2,141
  • 1
  • 22
  • 27
  • 34
    If subview lies outside of superview then control events do not fire. For sake of convenience set clipSubviews property of the superview to YES, so that you can identify the subviews frame visually. – dev gr Mar 27 '14 at 14:14
  • @devgr that hide my view elements that are outside from the superview height. I would like a way where to get the button working without care of its position : /, what could i do ? – Jorge Wander Santana Ureña Jul 01 '16 at 14:55
  • see it in the hierarchy which parent view is short – Naishta Jul 11 '17 at 16:17
  • see it using View Hierarchy button after running the app, as to which parent view that contains the button is short. This is the correct answer ! – Naishta Jul 11 '17 at 16:27
23

Make sure that your button is placed inside superView's bounds,
If a button is placed outside superView's bounds, the button will not clickable,
because of the implement of the hitTest function

saurabh
  • 6,687
  • 7
  • 42
  • 63
Shawn Wang
  • 2,314
  • 1
  • 16
  • 19
  • very helpful! Furthermore, following some of the answers from [this question](https://stackoverflow.com/questions/11770743/capturing-touches-on-a-subview-outside-the-frame-of-its-superview-using-hittest) resolved my issue completely. – David Nov 11 '18 at 11:51
17

I think you have placed your button on UIImageView, if so, you have to make UserInteraction enable for that UIImageView. Please check.

Ashutosh
  • 2,215
  • 14
  • 27
17

If a UITapGestureRecognizer is implemented on any of super View of your button. then UIButtonEventTouchUpInside wont be fired.

you should implement UITapGestureRecognizer like this

tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecognized:)];
[tapGesture setCancelsTouchesInView:NO]; // This should do what you want
[tapGesture setDelegate:self];
ooops
  • 761
  • 8
  • 18
Zeeshan
  • 4,194
  • 28
  • 32
5

Another thing to consider is have you placed another view on top of it?

For example if you load another view from a nib and incorrectly frame it then it may well appear on top of the button thus intercepting any presses.

You can check this is XCode 6 with the "Debug View Heirachy" control.

Thomas Clowes
  • 4,529
  • 8
  • 41
  • 73
5

Having layout looks like:

View -> Subview(UIView) -> Button

It's fixed by tick the "User Interaction Enabled" checkbox in the attributes of Subview(UIView).

Nianliang
  • 2,926
  • 3
  • 29
  • 22
3

If you have a parent UIView you can try to set its userInteractionEnabled property to True, in some cases it fixes the problem.

ParentView -> ChildView -> StackView -> UIButton

in this case I've set the userInteraction of ChildView to true and solved the problem.

Shahriyar
  • 520
  • 7
  • 18
2

Troubleshooting:

  • Make sure there isn't a hidden view in front of your button.
  • Make sure user interaction is not set to false.
ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
1

I had something similar recently;

Try deleting the (IBAction)favoritesButtonDepressed:(id)sender declaration (and method) in your Controller, and "dragging" it over from Interface Builder again.

Nayan
  • 3,014
  • 2
  • 17
  • 33
MDB983
  • 2,444
  • 17
  • 20
1

In my case IBAction for the button was not working I tried in many ways. So I made an IBOutlet for the button and added click action by using "addTarget" method it worked like a charm.

[myButton addTarget:self action:@selector(dismissClickFunction:) forControlEvents:UIControlEventAllEvents];
Smart guy
  • 494
  • 6
  • 9
1

Make sure the button.isEnabled is not getting set to false

Naishta
  • 11,885
  • 4
  • 72
  • 54
1

I had similar issue.

Open Debug View Hierarchy and make sure that none of the parent-views has height or width of zero.

In my case UIButtons were in a container (UIView) that was in a vertical UIStackView. I added a height constraint to the container and touch event started working.

Haseeb Iqbal
  • 1,455
  • 13
  • 20
0

I had the same problem.

I had a button in a xib that I placed inside a view.

I left the instance of the xib to its default small size set on import because I am resizing it automatically in code to handle device rotation.

That caused the button to not react to touch even if it was clearly in the middle of the screen.

I fixed it by simply changing the layout of the xib instance to fill the parent view.

Pic Mickael
  • 1,244
  • 19
  • 36
0

Check if there are any constraints missing. All the constraints should be balanced with no red lines. This fixed the issue for me.

Lax
  • 55
  • 11
0

My ViewController was a sub controller for an area within another ViewController. I deleted a bunch of controls in it to simplify, but the remaining button would no longer handle handle tap downs, despite being enabled, and all views having userInteraction enabled.

I tried creating a button dynamically, didn't work. Thinking I had a bad resource from original build, I deleted derived data, quit Xcode, deleted app and rebuild from scratch, no go.

Finally I tried drawing the parent view's background in yellow, didn't show up confirming the problem was it's frame. The parent view frame was something like (0,0,320,200) in storyboard, but in viewDidAppear it was only 0 points in height and offset by 150 points vertically. I tried setting it manually and thankfully that hack didn't work. So I did what you should always do with storyboards that misbehave, I burned it with fire!

Actually I deleted it and created a fresh storyboard to replace it, containing only the views and controls for the new design. Linked up to my ViewController code, and it worked without any problems.

SafeFastExpressive
  • 3,637
  • 2
  • 32
  • 39
0

if your UIButton is embedded inside a UIScrollView make sure that the scroll view property Delay Touch Down is disabled, this solved the issue for me

0

It depends on a variety of things and situations.

  1. Check Respond Chain of click by viewing hierarchy of a view and see maybe a view is top of another view and causes to click not working as you expected it's like Z-index in HTML!
  2. Check userInteraction for the view is set to enabled
  3. If you are using Storyboard check it's connected to correct action and check you haven't more than one action in the storyboard.
Hamed Hosseini
  • 182
  • 2
  • 13
0

I have implemented container view with full size of main controller view programmatically, and added button from storyboard. so you can use bringSubviewToFront to get particular button on top of all views.

Give the background color or container views and buttons. It will give proper idea about what's happening in view hierarchy.

KrishnDip
  • 81
  • 10