Infinite Possibilities
Infinite Possibilities

Reputation: 7476

UIGestureRecognizer ending

I would like to handle the rotation gesture in my iPhone app and rotate an imageView during this. At the end of the gesture I would like to rotate to a fix position the imageView. So ie. if I rotate the imageView from 0 radian to M_PI/2 radians, but somewhere on halfway I end with the gesture. After the end I would like to test the angle and if it close to M_PI/2 then set it to M_PI/2 otherwise to 0.
Here's my code how I tried to do this:

I create and add the recognizer to my view.

UIGestureRecognizer *recognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognized:)];
recognizer.delegate = self;
[self addGestureRecognizer:recognizer];
[recognizer release];

Delegate methods:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (_imageView) {
        return YES;
    }
    return NO;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

Gesture recognized method:

- (void)gestureRecognized:(UIRotationGestureRecognizer *)recognizer {
    _imageView.transform = CGAffineTransformMakeRotation(recognizer.rotation);
}

These methods are working, but here's the method how I tried to get the end of the gesture. This is not working:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"gesture end");
}

Also with the transform I have a little problem. Sometimes it is going back to the 0 radian.

Any suggestion is welcome. Thanks!

Upvotes: 12

Views: 15060

Answers (3)

Ben G
Ben G

Reputation: 3975

Just in case this happens to you as well and it's the reason you're reading that question : "ended" and "recognized" are the same value ( 3 ). So this code (in swift) won't work:

if (gesture.state == .recognized || gesture.state == .changed) {
}
else if (gesture.state == .ended) {
//do something else
//=> never called
}

Upvotes: 0

Infinite Possibilities
Infinite Possibilities

Reputation: 7476

I've found the answer on an other forum. I hope this will help somebody else too. Answer:

You can detect the end of the gesture by checking the UIRotationGestureRecognizer's state in your action method. If [gestureRecognizer state] == UIGestureRecognizerStateEnded then it's done. If something had instead caused it to be cancelled (for instance, a phone call coming in) then you'd see it end in UIGestureRecognizerStateCancelled instead.

If you want to apply the recognizer's rotation directly to your view rather than treat it as a delta from the previous location you can set the recognizer's rotation the its state is UIGestureRecognizerStateBegan, and then it will calculate offsets from that value and you can apply them directly. This just requires that you remember the rotation you last ended at, and then you can do something like [gestureRecognizer setRotation:lastAppliedRotation] when the recognizer's state is UIGestureRecognizerStateBegan.

Upvotes: 26

jakeva
jakeva

Reputation: 2835

If the gestureRecognizer recognizes the gesture, by default touchesEnded won't be called (touchesCancelled will be called instead. touchesEnded would only be called if the recognizer doesn't recognize the gesture). Set gestureRecognizer.delaysTouchesEnded to NO, and it should work.

Upvotes: 1

Related Questions