UIButton not receiving touches in iOS 13

My company has an app that's been around for years. Now, under iOS 13, some buttons on a particular View are not receiving touch events.


If I use a Symbolic Breakpoint for [UIWindow sendEvent] and then do a debugger command of po $arg3, it shows that a UIImageView a couple of views behind the buttons is receiving the touch event. There is no gesture recognizer on the UIImageView. There is a TapGestureRecognizer on the base view in a different view controller. That gesture recognizer has cancelsTouchesInView = NO.


Has anyone ran into this?

Answered by donmesserli2 in 403868022

Found the problem. The selectedRateView had a height constraint of 0 with a priority of 1000. This caused the view to have a height of 0 even though the code was trying to set it's frame. For some reason, the child controls were still visible; but not receiving events.


For some reason, this wasn't being enforced on older versions of iOS. The selectedRateView was the height specified when setting the frame in code and it's children were receiving touch events.


(I inherited this code)

Please tell more about the buttons.


Are they system button or custom ?

Have they an image ?

If so, how is the image defined ?

If it is an xcAsset, how is render defined ?


Then, could try this:

- select MyImage in xcAssets

- Open attributes inspector, look at the top, in Image Set:

- change 'Render As' from 'Default' to 'Original Image'.

Trying to find some hints.


How is button positionned relative to the view which "intercepts" the tap ?


How did you create the button ?

- In IB ?

- In code : please show the code, to check you have defined a button type when creating.


Have you checked you called super on viewDidLoad or siblings:

h ttps://forums.macrumors.com/threads/uibutton-not-responding-to-touch-events.2042335/


Did you look at constraints ?

May read this for a somehow similar case.


https://stackoverflow.com/questions/22987549/uibutton-not-getting-event-when-tapped

The buttons are added programmatically.


self.selectedRate1Button = [[UIButton alloc] initWithFrame:self.selectedRateLabel.frame];
        [self.selectedRate1Button addTarget:self action:@selector(selectedRateButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
        [self.selectedRate1Button setBackgroundColor:[UIColor clearColor]];
        self.selectedRate1Button.isAccessibilityElement = YES;
        self.selectedRate1Button.accessibilityLabel = @"RatesViewController_selectedRate1Button";
        [self.selectedRateView addSubview:self.selectedRate1Button];


I didn't write the app. It doesn't use AutoLayout at all.


The ViewSController IS call/ing [super ViewDidL=oad] in ViewDidLoad


The buttons ARE at the front.

Could you check what happens if you remove the tap gesture of the other view ?

How is this tap created ?

In code ? If so, could you show it ?


The buttons ARE at the front.

How did you check ?

What is your view hierarchy ? From what you posted, there are


View // Of the ViewController

some here ?

self.selectedRateView

// some here ? some overlapping the button ?

self.selectedRate1Button

// some more ?


Where is the view with the tapGesture in this hierarchy ?

Remember, this only stopped working under iOS 13


Removing the TapGestureRecognizer doesn't change the behaviour.


I used the View Hierarchy Debugger to make sure the buttons were in front.


The view hierarchy is...

View // Of base ViewController - TapGestureRecognizer is here

View // Of ViewController - pushed on Navigation stack

selectedRateVuew

Label x4 - each label has a button on top of it with the same frame

Button x4


I am going to try to remove the buttons and just put TapGestureRecognizers on the Labels

I tested a simpler conf:

View // Of ViewController

ImageView // TapGestureRecognizer is here, created in IB

Label

Button x4 // on top of button with the same frame



Hitting the button print the message of the button IBAction.

Of course User Interaction is ENABLED for the button


So it works here.

Removing the buttons and putting TapGestureRecognizers on the Labels (and setting userInteractionEnabled = YES didn't help.

It seems your button title is empty ?


If so, could you try to set a title for .normal ?

Setting a button title didn't help.

Very hard to search for the problem through foprum exchange. If you wish, you may post temprarily a mail address so that we can share complete project.

Accepted Answer

Found the problem. The selectedRateView had a height constraint of 0 with a priority of 1000. This caused the view to have a height of 0 even though the code was trying to set it's frame. For some reason, the child controls were still visible; but not receiving events.


For some reason, this wasn't being enforced on older versions of iOS. The selectedRateView was the height specified when setting the frame in code and it's children were receiving touch events.


(I inherited this code)

UIButton not receiving touches in iOS 13
 
 
Q