创建自定义的旋转手势

转载自Creating a Custom Rotation Gesture Recognizer for iOS Apps

创建自定义的旋转手势

主要重写了4个方法:

- (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

主要代码如下,原理见注释:

@protocol CAYSwirlGestureRecognizerDelegate <UIGestureRecognizerDelegate>

@end

@interface CAYSwirlGestureRecognizer : UIGestureRecognizer

@property CGFloat currentAngle;
@property CGFloat previousAngle;

@end

#import "CAYSwirlGestureRecognizer.h"

@interface CAYSwirlGestureRecognizer ()

@property (strong, nonatomic) id target;
@property (nonatomic) SEL action;

@end

@implementation CAYSwirlGestureRecognizer

- (id)initWithTarget:(id)target action:(SEL)action {

    if (self = [super initWithTarget:target action:action]) {
        self.target = target;
        self.action = action;
    }

    return self;
}


- (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];

    UITouch *touch = [touches anyObject];

    self.currentAngle = [self getTouchAngle:[touch locationInView:touch.view]];
    self.previousAngle = [self getTouchAngle:[touch previousLocationInView:touch.view]];

    if ([self.target respondsToSelector:self.action]) {
        [self.target performSelector:self.action withObject:self];

    }
}

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

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

- (float)getTouchAngle:(CGPoint)touch {

    // Translate into cartesian space with origin at the center of a 320-pixel square
    /*
     *1.这里的view的width是320宽的
     *2.相当于把view的原点从左上角,移动到中心点,并且把Y转的方向翻转,向上为正,并且0°位于Y轴
     */
    float x = touch.x - 160;
    float y = -(touch.y - 160);

    // Take care not to divide by zero!
    if (y == 0) {
        if (x > 0) {
            return M_PI_2;
        }
        else {
            return 3 * M_PI_2;
        }
    }

    float arctan = atanf(x/y);

    // Figure out which quadrant we're in

    // Quadrant I 第一象限
    if ((x >= 0) && (y > 0)) {
        return arctan;
    }
    // Quadrant II 第二象限
    else if ((x < 0) && (y > 0)) {
        return arctan + 2 * M_PI;
    }
    // Quadrant III
    else if ((x <= 0) && (y < 0)) {
        return arctan + M_PI;
    }
    // Quadrant IV
    else if ((x > 0) && (y < 0)) {
        return arctan + M_PI;
    }

    return -1;
}

@end

在View上添加手势:

self.swirlGestureRecognizer = [[CAYSwirlGestureRecognizer alloc] initWithTarget:self action:@selector(rotationAction:)];

[self.swirlGestureRecognizer setDelegate:self];

[self.controlsView addGestureRecognizer:self.swirlGestureRecognizer];

action方法主要是做变换旋转:

- (void)rotationAction:(id)sender {

    if([(CAYSwirlGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
        return;
    }

    CGFloat direction = ((CAYSwirlGestureRecognizer*)sender).currentAngle - ((CAYSwirlGestureRecognizer*)sender).previousAngle;

    bearing += 180 * direction / M_PI;

    if (bearing < -0.5) {
        bearing += 360;
    }
    else if (bearing > 359.5) {
        bearing -= 360;
    }

    CGAffineTransform knobTransform = self.knob.transform;

    CGAffineTransform newKnobTransform = CGAffineTransformRotate(knobTransform, direction);

    [self.knob setTransform:newKnobTransform];

    self.position.text = [NSString stringWithFormat:@"%dº", (int)lroundf(bearing)];
}

最终的效果如下:

最终的效果

代码CayuseConcepts/KnobRotation

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值