2010-09-21 24 views
5

我想旋转一个基于用户swipe.C圈的图像,我已经完成了考虑作为两部分。一个是左侧,另一个是右侧。 如果用户从右半侧向下滑动,则表示它顺时针旋转,向上滑动意味着反时钟。在左边我做了反过来。所以,现在只有当我触摸左右半边时,我的图像才会正常旋转..在触摸顶部和底部时..其行为不同。 我甚至试过NY计算弧度..其还没有工作 任何一个可以建议我来标识顺时针或anticlock以更好的方式明智...我如何使图像旋转基于我的手指滑动的方向

谢谢U, 拉克希米·琼斯

回答

1

有无你曾经尝试this教程为您的问题。这肯定会对你有所帮助。

计算刷卡

#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; 

与.m文件.h文件是

#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 

主要方法,这将有助于您跟踪刷卡是

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

愿这能帮助你:)

5

你应该用trignometry来解决这个问题。假设你知道刷卡的起点(A1,B1)和刷卡的结束点(A2,B2) 圆圈中心在(X,Y)

enter image description here

如果我们知道的差异(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 
    } 
} 

here知道如何计算晒黑逆。

同样计算角度绿色的值。做完之后,只需比较绿色和红色的值就可以让你知道该怎么做。

if(red - green == pi || red - green == 0){ 
    do_nothing();   
}else if(red - green > 0){ 
    rotate_clockwise();   
}else{ 
    rotate_anticlockwise(); 
} 

通过使用刷卡的加速度/速度数据,你可以用旋转相同的加速度/速度的圈子。

0

虽然三角学是数学的一种方法,但它更简单,并且需要更少的处理器能力才能完成此操作。

供参考图片:

enter image description here

的要旋转表盘中心点Ç

在用户界面上,你必须得到一个刷卡起点一个和“刷卡载体” 小号,显示了如何将用户的手指移动。如果OS只提供了一个第二点一段时间后,然后计算小号 = -

要计算的小号切线ç为中心的圆穿过一个的组件。这将允许用户在任何地方开始他/她的滑动,并将其作为关于点C的扭矩来对待。这应该是直观的。

这并不难。圆的半径显示为向量r = A-C。垂直于这个矢量被称为“r perp”,用图片中的“图钉”符号显示。它只是点(-y,x),其中x和y是r的组成部分。

p投影到PERP(ř)的签字长度只是一个归一化点积:

enter image description here

这是一个标量是正的,如果旋转是逆时针围绕C,顺时针方向为负。所以标志告诉你旋转的方向。绝对值告诉你旋转多少或多快。

假设我们已经刷卡矢量小号存储为sxsy和中心çcxcy。那么伪代码只是:

r_perp_x = cy - ay; r_perp_y = ax - cx; 
signed_length_p = (sx * r_perp_x + sy * r_perp_y)/sqrt(r_perp_x^2 + r_perp_y^2) 

所需号码是signed_length_p

唯一需要注意的是忽略触碰A接近C。他们可以产生非常大的输出值或零除。这很容易解决。只要检查r的长度,并退出,如果它低于一些合理的价值。

0

如果你目前的解决方案对你来说“几乎没有问题” - 最简单的做法是......只是两个区域固定它: starting swipe areas

现在你的图像顺时针您的旋转,每当用户刷卡
- 右或上(开始A区)
- 向右或向下(B区启动)
- 向左或向下(始于区d)
- 向左或向上(C区启动)

....其他 - 逆时针旋转它。