Reputation: 98
I have a subclassed UIView
, let's call it TileView.m/h
.
In TileView.m
, I have the following code: ([setup]
is definitely being called, I checked with breakpoints).
- (void)setup {
self.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(testPressed:)];
[self addGestureRecognizer:tap];
}
- (void)testPressed:(UITapGestureRecognizer *)sender {
NSLog(@"tap pressed");
}
For some reason, the testPressed
method is not called when I tap the view!
Strangely, if I copy the TileView
class into a blank xCode project and set it up there, everything works absolutely fine. This is peculiar since gestures are handled first by subviews and then by superviews - so the tile class shouldn't be affected by its superviews. Also the gesture is fully contained within the TileView
class.
For reference, the tile view is nested fairly deeply in a:
Controller -> controller's view -> scroll view -> container view -> tile view
pattern.
I have tried without success:
tap.delegate = self
and then implementing gestureRecognizer:shouldRecognizeSimultaneously...
to always return YES;
No luck :/
Any ideas for what else could be going wrong? Or what tests can I run to understand the problem in more detail?
EDIT: More details
Recall that the tile view is nested in: Controller -> controller's view -> scroll view -> container view -> tile view
If I add a gesture recognizer in the controller file with:
[self.view addGestureRecognizer:tap]
and then use [self.view hitTest:[sender locationInView:self.view] withEvent:nil];
in the event handler, I can see that the returned view is a UIScrollView
and not a TileView
as would be expected.
Additionally, adding the gesture recognizer to self.scrollView
instead works fine, but stops working if I add it to self.containerView
(which is the only subview of scrollView
). containerView
has userInteractionEnabled = YES
.
Upvotes: 1
Views: 2830
Reputation: 7187
The reason why its not firing is because you are not keeping a reference to your UITapGestureRecognizer
. As soon as setup
function returns your UITapGestureRecognizer
gets deallocated.
If you want it to work save it to a property:
@property (strong, nonatomic) UITapGestureRecognizer *tapRecognizer;
- (void)setup {
self.tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(testPressed:)];
[self addGestureRecognizer:self.tapRecognizer];
}
- (void)testPressed:(UITapGestureRecognizer *)sender {
NSLog(@"tap pressed");
}
Upvotes: 0
Reputation: 4516
You might also want to check that you're not trying to reuse the UITapGestureRecognizer
object for different views.
It seems like it's possible because you're just appending the gesture to the view, but in ultimately the view needs to be assigned to the view property on the gesture object so adding the gesture object to a second view will just overwrite the first.
Upvotes: 0
Reputation: 80265
If the view contains subviews that are UIImageView
s, remember that you have to explicitly set the userInteractionEnabled
to YES
(the default is NO
).
If not, the image views will prevent the tap from reaching the superview.
Also, remember to set the number of touches.
Upvotes: 9