我设法得到了一些不错的结果。
我是如何做到的,应该进行更多调整,但这是基础:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
rotation = _startAngle = atan2(384 - touchPoint.y, 512 - touchPoint.x);
[_history removeAllObjects];
};
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
[_history insertObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:CFAbsoluteTimeGetCurrent()], @"time", [NSValue valueWithCGPoint:touchPoint], @"point", [NSNumber numberWithFloat: _circleRotationOffset + rotation], @"rotation", nil] atIndex:0];
if ([_history count] == 3) {
[_history removeLastObject];
}
rotation = atan2(384 - touchPoint.y, 512 - touchPoint.x) - _startAngle;
[circleImage setTransform:CGAffineTransformMakeRotation(_circleRotationOffset + rotation)];
};
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint tp = [[touches anyObject] locationInView:self.view];
_circleRotationOffset += rotation;
NSDictionary *lo = [_history lastObject];
CGPoint pp = [[lo objectForKey:@"point"] CGPointValue];
double timeDif = CFAbsoluteTimeGetCurrent() - [[lo objectForKey:@"time"] doubleValue];
float lastRotation = [[lo objectForKey:@"rotation"] floatValue];
// Calculate strength
float dist = sqrtf(((pp.x - tp.x) * (pp.x - tp.x)) + ((pp.y - tp.y) * (pp.y - tp.y)));
float strength = MIN(1.0f, dist / 80.0f) * (timeDif / .025) * M_PI;
float p = _circleRotationOffset;
float dif = _circleRotationOffset - lastRotation;
BOOL inc = dif > 0;
if (dif > 3 || dif < -3) { // Some correction
inc = !inc;
}
if (inc) {
_circleRotationOffset += strength;
} else {
_circleRotationOffset -= strength;
}
[circleImage.layer removeAllAnimations];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = MAX(strength / 2.5, 1.0f);
animation.cumulative = YES;
animation.repeatCount = 1;
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:p],
[NSNumber numberWithFloat: _circleRotationOffset], nil];
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:1.0], nil];
animation.timingFunctions = [NSArray arrayWithObjects:
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil];
animation.removedOnCompletion = YES;
animation.delegate = self;
animation.fillMode = kCAFillModeForwards;
[circleImage.layer addAnimation:animation forKey:@"rotate"];
};