How can I find out when a pinch gesture is finished (UIGestureRecognizer) - iphone

I want to get a callback when my UIPinchGestureRecognizer finished a pinch-gesture. Moreover it would be great to know if the finished gesture was a zoom in or a zoom out.
Does anyone know a method to use? Or the approach to do?
Thanks!

Another approach instead of overriding touchesEnded:, is that you could just check the state of the gesture recognizer in your target handler method.
-(void)handlePinchGesture:(UIGestureRecognizer*)gestureRecognizer {
if(UIGestureRecognizerStateEnded == [gestureRecognizer state]){
// do something
}
}

You can know if it was a zoom in or out by the scale property of the UIPinchGestureRecognizer.
Just overrride it's touchesEnded: method to get a callback (and the call some other method if you wish).

The best approach which does not require subclassing is to examine the "state" property on the gesture recognized instance in your action handler. The state will change during all phases of the lifecycle of the gesture. The state change you're looking for is UIGestureRecognizerStateEnded. It is also good practice to check for UIGestureRecognizerStateCancelled as well.

Related

Detecting a finger being held on an object

I am trying to have an image that when the user touches it, it wiggles and as soon as the user lifts their finger it stops.
Is there a gesture that I can use to detect when the finger is down, not just on the initial touch, or when the user moves there finger?
I have tried a LongPress gesture, but that does not get called the entire time the finger is on the view. Can anyone help me with the best way to active this. Right now i am doing it using touchesBegin, touchesMoved, touchesEnd, but i was wondering if there is a better way.
Any suggestions are greatly appreciated.
Thanks
EDIT
Based on the comments, I slightly misunderstood the original question, so I edit my answer to a different solution, which hopefully is a bit more clear (and answers the actual question - not the one that was in my head).
A LongPress gesture is continuous (where a tap gesture is not). That means, the recognizer callback will continue to be invoked until the gesture is complete - which does not happen until the "longpress" is released. So, the following should do what you want. NOTE: I think you want to "start shaking" a view when the long-press is recognized, then "stop shaking" the view when the fingers are released. I just pretended you have functions for that. Substitute appropriately.
- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
StartShakingView(gestureRecognizer.view);
} else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
StopShakingView(gestureRecognizer.view);
}
}
The Apple Touches sample includes code that demonstrate using both UIResponder and UIGestureRecognizer methods.
Either should work for what you're doing.
Simple answer - you could make the image a UIButton, and start the wiggle on TouchDown, and stop it on TouchUpInside or TouchUpOutside
It sounds like you want to subclass UIGestureRecognizer, which, as I recall, gets the touchesBegan:... and associated methods. Read the notes on subclassing in the UIGestureRecognizer reference. Or use a UIButton as SomaMan suggests.

MBProgressHUD tap to cancel, longer text?

I'd like to use MBProgressHUD (or similar look) as alternative to default UIAlertView.
I need a canceling capability on this view.
I tried adding the following method to MBProgressHUD class but it didn't get called when touched.
Any idea?
(void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*)event
I can't use gesture recognizer since my lowest target version is 3.1.2.
Also, it seems complex to enlarge label size for MBProgressHUD's text.
Are there altanatives than fixing MBProgessHUD for the purpose?
I just had quick look at MBProgressHUD and would use that. First, change the size of the HUD by modifying layoutSubviews in MBProgressHUD.h. I would then create a new button class (UIButton subclass) and add this as a subview of the HUD.
This is a super old thread, but it would be way easier just to set hud's UserInteractionEnabled:YES and add a tapGestureRecognizer to it.
Cheers.

Swipe Gestures and drawing user touches error

i have UISwipeGestureRecognizer that detects if the user has swiped. i also draw the users touches using the touches moved method found in the tutorial below.
http://www.ifans.com/forums/showthread.php?t=132024
My issue is the gesture seems to override my drawing. is it possible to do both or is there a better way of doing this?
Thanks
Dan
All of the touches methods get overridden when you invoke a gestureRecognizer. You can view it here in the explanation. It may be best to just write your own code to recognize a gesture if you need all of the touch events for drawing updates. If you still want to use a gestureRecognizer, you can use the locationInView: method to find the location of the touch, and then pass those points to your draw method.
I would also think about using OpenglES instead, as it isa bit easier, and you can do more things. There's a great sample project about it here. Hope that helps!

When touches Cancelled method get invoked in iPhone?

I am able to understand that when user just touches the view, touches Began and Ended called. When user swipes their hand on a view, touches Moved method gets called. But when does touches Cancelled get called or by what action on user this method gets called?
I think probably the most common reason for touchesCancelled being called (since iOS 3.2 anyway) is following the recognition of a gesture by a UIGestureRecognizer. If your view has any kind of gesture recognizer attached to it then it is often very important to provide a custom implementation of the touchesCancelled method - note this includes ready made views that use gesture recognizers, including UIScrollView.
By default, gesture recognizers cancel the delivery of touches to the hit-test view upon recognition, although this behaviour can be disabled. This involves sending the touchesCancelled message to that view, most likely following a touchesBegan or touchesMoved message. If your touch handling code is relying on code implemented in the touchesEnded method, it is possible this may never be fired and some kind of serious problem could occur, hence the need to properly tie up any loose ends in touchesCancelled.
The ins and outs of gesture recognizer functionality is obviously a bit more complex than I've mentioned here - I would thoroughly recommend reading Apple's Gesture Recognizers documentation.
Also, check out the WWDC videos on gesture recognizers (starting from 2010).
Note: touches also get cancelled if you start a UIView animation after touchesBegan. To prevent this make sure you include UIViewAnimationOptionAllowUserInteraction:
e.g.
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.aView.hidden = NO;
self.aView.alpha = 1;
} completion:nil];
From the Apple Reference documents
Sent to the receiver when a system
event (such as a low-memory warning)
cancels a touch event.
Discussion
This method is invoked when the Cocoa
Touch framework receives a system
interruption requiring cancellation of
the touch event; for this, it
generates a UITouch object with a
phase of UITouchPhaseCancel. The
interruption is something that might
cause the application to be no longer
active or the view to be removed from
the window
When an object receives a
touchesCancelled:withEvent: message it
should clean up any state information
that was established in its
touchesBegan:withEvent:
implementation.
The default implementation of this
method does nothing. However immediate
UIKit subclasses of UIResponder,
particularly UIView, forward the
message up the responder chain.
And, from the Event Handling Guide for iOS, p. 19:
It sends the touchesCancelled:withEvent: message when the touch sequence is cancelled by a system event, such as an incoming phone call.
I was handling touchesBegan()/touchesMoved() on a view under UIScrollView, which is challenging. My touches kept cancelled by somewhere when I pinch (somehow it is OK with single touch movement), I was investigating how to stop being cancelled. I figured out, that there is a property Can Cancel On Scroll on UIScrollView, and you may check it off to stop being cancelled, if your case is similar to my case.
It sounds there are many cases where your touches are being cancelled, so my answer is just one of them.

Does a UIPanGestureRecognizer take precedence over the -touchesMoved: method?

I'm not sure about this, but does a UIPanGestureRecognizer take precedence over a UIView's touch handling methods when it is added to that view? That is, will I still receive -touchesMoved: method calls from that view, or will I only get the callback from the gesture recognizer?
I believe it takes precedence over the touches handling callbacks. And it calls touhesCancelled before giving it to UIPanGestureRecognizer, if you have implemented it.