自定义手势识别器不与UIImageView一起工作

问题描述:

我正在实现一个使用dysternis » An one finger rotation gesture recognizer的自定义单指旋转手势,并且图像旋转得很好,但我有另一个按钮,点击它时有一些事件,但现在我必须触摸拖动该按钮来触发事件。自定义手势识别器不与UIImageView一起工作

我曾尝试将相同的手势识别器添加到图像视图中,但效果并不理想。它没有正确旋转图像。有没有需要改变的东西,或者我错过了一些东西。

这里是我的代码的编辑版本。请注意,我已启用用户与UIImageView的交互。

在OneFingerRotationGestureRecognizer.h文件:

#import <Foundation/Foundation.h> 
#import <UIKit/UIGestureRecognizerSubclass.h> 

@protocol OneFingerRotationGestureRecognizerDelegate <NSObject> 
@optional 
- (void) rotation: (CGFloat) angle; 
- (void) finalAngle: (CGFloat) angle; 
@end 

@interface OneFingerRotationGestureRecognizer : UIGestureRecognizer 
{ 
CGPoint midPoint; 
CGFloat innerRadius; 
CGFloat outerRadius; 
CGFloat cumulatedAngle; 
id <OneFingerRotationGestureRecognizerDelegate> target; 
} 

- (id) initWithMidPoint: (CGPoint) midPoint 
      innerRadius: (CGFloat) innerRadius 
      outerRadius: (CGFloat) outerRadius 
       target: (id) target; 
- (void)reset; 
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 

@end 

在OneFingerRotationGestureRecognizer.m文件

#include <math.h> 

#import "OneFingerRotationGestureRecognizer.h" 

@implementation OneFingerRotationGestureRecognizer 

// private helper functions 
CGFloat distanceBetweenPoints(CGPoint point1, CGPoint point2); 
CGFloat angleBetweenLinesInDegrees(CGPoint beginLineA, 
            CGPoint endLineA, 
            CGPoint beginLineB, 
            CGPoint endLineB); 

- (id) initWithMidPoint: (CGPoint) _midPoint 
      innerRadius: (CGFloat) _innerRadius 
      outerRadius: (CGFloat) _outerRadius 
       target: (id <OneFingerRotationGestureRecognizerDelegate>) _target 
{ 
    if ((self = [super initWithTarget: _target action: nil])) 
    { 
     midPoint = _midPoint; 
     innerRadius = _innerRadius; 
     outerRadius = _outerRadius; 
     target  = _target; 
    } 
    return self; 
} 

/** Calculates the distance between point1 and point 2. */ 
CGFloat distanceBetweenPoints(CGPoint point1, CGPoint point2) 
{ 
    CGFloat dx = point1.x - point2.x; 
    CGFloat dy = point1.y - point2.y; 
    return sqrt(dx*dx + dy*dy); 
} 

CGFloat angleBetweenLinesInDegrees(CGPoint beginLineA, 
            CGPoint endLineA, 
            CGPoint beginLineB, 
            CGPoint endLineB) 
{ 
    CGFloat a = endLineA.x - beginLineA.x; 
    CGFloat b = endLineA.y - beginLineA.y; 
    CGFloat c = endLineB.x - beginLineB.x; 
    CGFloat d = endLineB.y - beginLineB.y; 

    CGFloat atanA = atan2(a, b); 
    CGFloat atanB = atan2(c, d); 

    // convert radiants to degrees 
    return (atanA - atanB) * 180/M_PI; 
} 

#pragma mark - UIGestureRecognizer implementation 

- (void)reset 
{ 
    [super reset]; 
    cumulatedAngle = 0; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; 

    if ([touches count] != 1) 
    { 
     self.state = UIGestureRecognizerStateFailed; 

     return; 
    } 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesMoved:touches withEvent:event]; 

    if (self.state == UIGestureRecognizerStateFailed) return; 

    CGPoint nowPoint = [[touches anyObject] locationInView: self.view]; 
    CGPoint prevPoint = [[touches anyObject] previousLocationInView: self.view]; 

    // make sure the new point is within the area 
    CGFloat distance = distanceBetweenPoints(midPoint, nowPoint); 
    if ( innerRadius <= distance 
     && distance <= outerRadius) 
    { 
     // calculate rotation angle between two points 
     CGFloat angle = angleBetweenLinesInDegrees(midPoint, prevPoint, midPoint, nowPoint); 

     // fix value, if the 12 o'clock position is between prevPoint and nowPoint 
     if (angle > 180) 
     { 
      angle -= 360; 
     } 
     else if (angle < -180) 
     { 
      angle += 360; 
     } 

     // sum up single steps 
     cumulatedAngle += angle; 

     // call delegate 
     if ([target respondsToSelector: @selector(rotation:)]) 
     { 
      [target rotation:angle]; 
     } 
    } 
    else 
    { 
     // finger moved outside the area 
     self.state = UIGestureRecognizerStateFailed; 
    } 
    } 

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
    [super touchesEnded:touches withEvent:event]; 

    if (self.state == UIGestureRecognizerStatePossible) 
    { 
     self.state = UIGestureRecognizerStateRecognized; 

     if ([target respondsToSelector: @selector(finalAngle:)]) 
     { 
      [target finalAngle:cumulatedAngle]; 
     } 
    } 
    else 
    { 
     self.state = UIGestureRecognizerStateFailed; 
    } 

    cumulatedAngle = 0; 
    } 

    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
    [super touchesCancelled:touches withEvent:event]; 

    self.state = UIGestureRecognizerStateFailed; 
    cumulatedAngle = 0; 
    } 

    @end 

在View Contoller.m文件:

@interface deviceDetailViewController() 
{ 
    @private CGFloat imageAngle; 
    @private OneFingerRotationGestureRecognizer *gestureRecognizer; 
} 

- (void) updateTextDisplay; 
- (void) setupGestureRecognizer; 
@end 

@implementation deviceDetailViewController 
- (void)viewDidLoad 
{ 
    [self setupGestureRecognizer]; 

    [super viewDidLoad]; 
} 
#pragma mark - CircularGestureRecognizerDelegate protocol 

- (void) rotation: (CGFloat) angle 
{ 
    // calculate rotation angle 
    imageAngle += angle; 
    if (imageAngle > 360) 
     imageAngle -= 360; 
    else if (imageAngle < -360) 
     imageAngle += 360; 

    // rotate image and update text field 
    deviceRotator.transform = CGAffineTransformMakeRotation(imageAngle * M_PI/180); 

    [self updateTextDisplay]; 
} 

- (void) finalAngle: (CGFloat) angle 
{ 
    // circular gesture ended, update text field 
    [self updateTextDisplay]; 
} 

#pragma mark - Helper methods 

// Updates the text field with the current rotation angle. 
- (void) updateTextDisplay 
{ 
    textDisplay.text = [NSString stringWithFormat: @"\u03b1 = %.2f", imageAngle]; 
} 

// Addes gesture recognizer to the view (or any other parent view of image. Calculates  midPoint 
// and radius, based on the image position and dimension. 
- (void) setupGestureRecognizer 
{ 
    // calculate center and radius of the control 
    CGPoint midPoint = CGPointMake(deviceRotator.frame.origin.x + deviceRotator.frame.size.width/2,deviceRotator.frame.origin.y + deviceRotator.frame.size.height/2); 
    CGFloat outRadius = deviceRotator.frame.size.width/2; 

    // outRadius/3 is arbitrary, just choose something >> 0 to avoid strange 
    // effects when touching the control near of it's center 
    gestureRecognizer = [[OneFingerRotationGestureRecognizer alloc] initWithMidPoint: midPoint 
                     innerRadius: outRadius/3 
                     outerRadius: outRadius 
                       target: self]; 
    // [self.deviceRotator addGestureRecognizer:gestureRecognizer]; 
    [self.view addGestureRecognizer: gestureRecognizer]; 
} 
@end 
+0

显示您的代码以获得帮助。 – 2012-04-18 16:01:45

我加入这个自定义手势整个看法,但实施了另一个UITapGestureRecognizer其按钮精灵,现在它工作得很好。

+0

似乎OneFingerRotationGestureRecognizer不能在ios7上工作?我将它部署在ios7上,并且图像在旋转时总是波动。任何意见? – chipbk10 2014-06-03 12:35:25