Reputation: 55623
I'm learning iOS development and I'm looking at UIGestureRecognizer
's.
I have a view. When you tap that view, I want to show a UIPopoverController
and I also want it to act like a UIButton
in that it "highlights" when you press it.
The way I thought to do this was to use 2 UIGestureRecognizer
's - a UITapGestureRecognizer
and a UILongPressGestureRecognizer
The problem I'm running into is the highlight method gets called immediately (which I want) but if I then move my finger far enough, the UITapGestureRecognizer
gets cancelled. At that point, I want to call another method (unhighlight
) to restore the UIView
's initial background color, but I'm lost on how to do this.
I'm quite new to this, so this question is probably basic, and I appreciate any help that anybody can give me.
In the UIViewController
:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(togglePopover)];
[self.view addGestureRecognizer:tap];
UILongPressGestureRecognizer *press = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(highlight)];
press.minimumPressDuration = 0.f; //highlight immediately
press.delegate = self; //set the delegate to self
[self.view addGestureRecognizer:highlight];
//the delegate part of the UIViewController
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithOtherGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {
return YES; //allows allow simultaneous recognition of gestures on this view
}
Upvotes: 1
Views: 358
Reputation: 8309
If the behaviour you desired is like a UIButton
, why can't you just use a UIButton
?
Otherwise, you have to capture the state of the gesture inside your target method. While declaring the action-target for the gesture recognizer, make sure you put a colon after the target name.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(togglePopover:)];
Now, inside -togglePopover
, read the state
property of the passed gesture recognizer. That is documented here. You are looking for the state UIGestureRecognizerStateCancelled
.
Upvotes: 0
Reputation: 69027
A UITapGestureRecognizer
has a given behaviour, which you have just described in your concrete case.
What you are after could be done with a continuous gesture recognizer like UIPanGestureRecognizer
.
Specifically, a continuos gesture recogniser action method will receive a sequence of calls according to the states tge gesture recognizer goes thru.
One of those states is UIGestureRecognizerStateCancelled
, so you can manage it to detect when the gesture has been cancelled, like in your case, and act accordingly by removing the highlight. On the other hand, when your action is called in the UIGestureRecognizerStateBegan
state, you would highlight the button.
Your action method would be like this:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
...
} else if (recognizer.state == UIGestureRecognizerStateCancelled) {
...
}
}
Another approach altogether would be creating your own gesture recognizer subclass, where you would handle touchesBegan:/touchesMoved:/touchesEnded:
methods to suit your needs.
If you give a look at the UIGestureRecognizer reference you will find plenty of information.
Upvotes: 1