如何根据手指滑动的方向使图像旋转

Lak*_*nes 5 iphone-sdk-3.0

我正在尝试根据用户滑动来旋转圆形图像.现在我已经考虑了两个部分.一个是左侧,另一个是右侧.如果用户从右半部分向下滑动则意味着它顺时针旋转并且向上滑动意味着反时钟.在左侧,我做了反过来.所以现在我的图像只有当我触摸左半边和右半边时才会旋转...触摸顶部和底部..它的表现不同.我甚至试过计算弧度......它也不起作用任何人都建议我以更好的方式识别顺时针或逆时针......

谢谢你,拉克希米琼斯

小智 5

你应该用trignometry来解决这个问题.假设您知道滑动的起点(a1,b1)和滑动的终点(a2,b2)圆心位于(x,y)

在此输入图像描述

如果我们知道由线(x,y) - >(a1,b1)和(x,y) - >(a2,b2)产生的角度的差异,我们将根据上述是否知道是顺时针还是逆时针旋转角度是正面还是负面.

由线构成的角度计算如下.让红色角度为红色

if(a1-x==0){
    if(b1-y>0) red=pi/2
    else red = 3*pi/2
}
else{
  tan(red) = abs((b1-y)/(a1-x))
  red = tan-inverse( abs((b1-y)/(a1-x)) )
  if(a1-x<0){
    if(b1-y<=0)
        red+=pi;
    else
        red+=pi/2
  }
  else if(a1-x>0 && b1-y<0){
      red+=3*pi/2
  }
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处以了解如何计算tan-inverse.

同样地计算角度绿色的值.这样做之后只需比较绿色和红色的值就会让你知道该怎么做.

if(red - green == pi || red - green == 0){
    do_nothing();        
}else if(red - green > 0){
    rotate_clockwise();        
}else{
    rotate_anticlockwise();
}
Run Code Online (Sandbox Code Playgroud)

通过使用滑动的加速度/速度数据,您可以使用相同的加速度/速度旋转圆.


The*_*Dev 1

您是否尝试过教程来解决您的问题。这肯定会对你有帮助。

用于计算滑动的 .h 文件

#import <UIKit/UIKit.h>
#import "SMRotaryProtocol.h"

@interface SMRotaryWheel : UIControl

@property (weak) id <SMRotaryProtocol> delegate;
@property (nonatomic, strong) UIView *container;
@property int numberOfSections;
@property CGAffineTransform startTransform;
@property (nonatomic, strong) NSMutableArray *cloves;
@property int currentValue;


- (id) initWithFrame:(CGRect)frame andDelegate:(id)del withSections:(int)sectionsNumber;
Run Code Online (Sandbox Code Playgroud)

.m 文件是

#import "SMRotaryWheel.h"
#import <QuartzCore/QuartzCore.h>
#import "SMCLove.h"

@interface SMRotaryWheel()
    - (void)drawWheel;
    - (float) calculateDistanceFromCenter:(CGPoint)point;
    - (void) buildClovesEven;
    - (void) buildClovesOdd;
    - (UIImageView *) getCloveByValue:(int)value;
    - (NSString *) getCloveName:(int)position;
@end

static float deltaAngle;
static float minAlphavalue = 0.6;
static float maxAlphavalue = 1.0;

@implementation SMRotaryWheel

@synthesize delegate, container, numberOfSections, startTransform, cloves, currentValue;


- (id) initWithFrame:(CGRect)frame andDelegate:(id)del withSections:(int)sectionsNumber {

    if ((self = [super initWithFrame:frame])) {

        self.currentValue = 0;
        self.numberOfSections = sectionsNumber;
        self.delegate = del;
        [self drawWheel];

    }
    return self;
}



- (void) drawWheel {

    container = [[UIView alloc] initWithFrame:self.frame];

    CGFloat angleSize = 2*M_PI/numberOfSections;

    for (int i = 0; i < numberOfSections; i++) {

        UIImageView *im = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"segment.png"]];

        im.layer.anchorPoint = CGPointMake(1.0f, 0.5f);
        im.layer.position = CGPointMake(container.bounds.size.width/2.0-container.frame.origin.x, 
                                        container.bounds.size.height/2.0-container.frame.origin.y); 
        im.transform = CGAffineTransformMakeRotation(angleSize*i);
        im.alpha = minAlphavalue;
        im.tag = i;

        if (i == 0) {
            im.alpha = maxAlphavalue;
        }

        UIImageView *cloveImage = [[UIImageView alloc] initWithFrame:CGRectMake(12, 15, 40, 40)];
        cloveImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"icon%i.png", i]];
        [im addSubview:cloveImage];

        [container addSubview:im];

    }

    container.userInteractionEnabled = NO;
    [self addSubview:container];

    cloves = [NSMutableArray arrayWithCapacity:numberOfSections];

    UIImageView *bg = [[UIImageView alloc] initWithFrame:self.frame];
    bg.image = [UIImage imageNamed:@"bg.png"];
    [self addSubview:bg];

    UIImageView *mask = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 58, 58)];
    mask.image =[UIImage imageNamed:@"centerButton.png"] ;
    mask.center = self.center;
    mask.center = CGPointMake(mask.center.x, mask.center.y+3);
    [self addSubview:mask];

    if (numberOfSections % 2 == 0) {

        [self buildClovesEven];

    } else {

        [self buildClovesOdd];

    }

    [self.delegate wheelDidChangeValue:[self getCloveName:currentValue]];


}


- (UIImageView *) getCloveByValue:(int)value {

    UIImageView *res;

    NSArray *views = [container subviews];

    for (UIImageView *im in views) {

        if (im.tag == value)
            res = im;

    }

    return res;

}

- (void) buildClovesEven {

    CGFloat fanWidth = M_PI*2/numberOfSections;
    CGFloat mid = 0;

    for (int i = 0; i < numberOfSections; i++) {

        SMClove *clove = [[SMClove alloc] init];
        clove.midValue = mid;
        clove.minValue = mid - (fanWidth/2);
        clove.maxValue = mid + (fanWidth/2);
        clove.value = i;


        if (clove.maxValue-fanWidth < - M_PI) {

            mid = M_PI;
            clove.midValue = mid;
            clove.minValue = fabsf(clove.maxValue);

        }

        mid -= fanWidth;


        NSLog(@"cl is %@", clove);

        [cloves addObject:clove];

    }

}


- (void) buildClovesOdd {

    CGFloat fanWidth = M_PI*2/numberOfSections;
    CGFloat mid = 0;

    for (int i = 0; i < numberOfSections; i++) {

        SMClove *clove = [[SMClove alloc] init];
        clove.midValue = mid;
        clove.minValue = mid - (fanWidth/2);
        clove.maxValue = mid + (fanWidth/2);
        clove.value = i;

        mid -= fanWidth;

        if (clove.minValue < - M_PI) {

            mid = -mid;
            mid -= fanWidth; 

        }


        [cloves addObject:clove];

        NSLog(@"cl is %@", clove);

    }

}

- (float) calculateDistanceFromCenter:(CGPoint)point {

    CGPoint center = CGPointMake(self.bounds.size.width/2.0f, self.bounds.size.height/2.0f);
    float dx = point.x - center.x;
    float dy = point.y - center.y;
    return sqrt(dx*dx + dy*dy);

}

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint touchPoint = [touch locationInView:self];
    float dist = [self calculateDistanceFromCenter:touchPoint];

    if (dist < 40 || dist > 100) 
    {
        // forcing a tap to be on the ferrule
        NSLog(@"ignoring tap (%f,%f)", touchPoint.x, touchPoint.y);
        return NO;
    }

    float dx = touchPoint.x - container.center.x;
    float dy = touchPoint.y - container.center.y;
    deltaAngle = atan2(dy,dx); 

    startTransform = container.transform;

    UIImageView *im = [self getCloveByValue:currentValue];
    im.alpha = minAlphavalue;

    return YES;

}

- (BOOL)continueTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
{

    CGPoint pt = [touch locationInView:self];

    float dist = [self calculateDistanceFromCenter:pt];

    if (dist < 40 || dist > 100) 
    {
        // a drag path too close to the center
        NSLog(@"drag path too close to the center (%f,%f)", pt.x, pt.y);

        // here you might want to implement your solution when the drag 
        // is too close to the center
        // You might go back to the clove previously selected
        // or you might calculate the clove corresponding to
        // the "exit point" of the drag.

    }

    float dx = pt.x  - container.center.x;
    float dy = pt.y  - container.center.y;
    float ang = atan2(dy,dx);

    float angleDifference = deltaAngle - ang;

    container.transform = CGAffineTransformRotate(startTransform, -angleDifference);

    return YES;

}

- (void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
{

    CGFloat radians = atan2f(container.transform.b, container.transform.a);

    CGFloat newVal = 0.0;

    for (SMClove *c in cloves) {

        if (c.minValue > 0 && c.maxValue < 0) { // anomalous case

            if (c.maxValue > radians || c.minValue < radians) {

                if (radians > 0) { // we are in the positive quadrant

                    newVal = radians - M_PI;

                } else { // we are in the negative one

                    newVal = M_PI + radians;                    

                }
                currentValue = c.value;

            }

        }

        else if (radians > c.minValue && radians < c.maxValue) {

            newVal = radians - c.midValue;
            currentValue = c.value;

        }

    }

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.2];

    CGAffineTransform t = CGAffineTransformRotate(container.transform, -newVal);
    container.transform = t;

    [UIView commitAnimations];

    [self.delegate wheelDidChangeValue:[self getCloveName:currentValue]];

    UIImageView *im = [self getCloveByValue:currentValue];
    im.alpha = maxAlphavalue;

}

- (NSString *) getCloveName:(int)position {

    NSString *res = @"";

    switch (position) {
        case 0:
            res = @"Circles";
            break;

        case 1:
            res = @"Flower";
            break;

        case 2:
            res = @"Monster";
            break;

        case 3:
            res = @"Person";
            break;

        case 4:
            res = @"Smile";
            break;

        case 5:
            res = @"Sun";
            break;

        case 6:
            res = @"Swirl";
            break;

        case 7:
            res = @"3 circles";
            break;

        case 8:
            res = @"Triangle";
            break;

        default:
            break;
    }

    return res;
}



@end
Run Code Online (Sandbox Code Playgroud)

帮助您跟踪滑动的主要方法是

- (float) calculateDistanceFromCenter:(CGPoint)point

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

- (BOOL)continueTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event

- (void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
Run Code Online (Sandbox Code Playgroud)

希望这会帮助你:)