Поворот изображения, соответствующего сенсорному перетаскиванию в iPhone
Я хочу повернуть изображение в направлении по часовой стрелке или против часовой стрелки, соответствующем скорости перетаскивания пользователем сенсорного экрана. Я думаю, что это можно сделать с помощью математики и логики. Как будет выглядеть пример кода для этого?
3 ответа:
Если вы нацелены на iOS 3.2 или выше, вы можете использовать
UIRotationGestureRecognizer
. Код будет выглядеть примерно так:В вашем методе установки (
viewDidLoad
илиinit
и т. д.):UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotate:)]; rotationGesture.delegate = self; [myImageView addGestureRecognizer:rotationGesture]; [rotationGesture release];
Обработчик событий:
- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer { if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged) { recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation); [recognizer setRotation:0]; } }
У меня есть еще несколько примеров распознавания жестов (включая приведенный выше) на github.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { currentTouch=touch; if (CGRectContainsPoint([self.view frame], [touch locationInView:self.ViewRotationArrow])) { [self transformSpinnerwithTouches:touch]; } else if (!CGRectContainsPoint([ViewRotationArrow frame], [touch locationInView:self.ViewRotationArrow])) { [self dispatchTouchEvent:[touch view]WithTouch:touch]; } } } -(void)transformSpinnerwithTouches:(UITouch *)touchLocation { CGPoint touchLocationpoint = [touchLocation locationInView:self.view]; CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view]; //Origin is the respective point. From that I am going to measure the //angle of the current position with respect to the previous position .... CGPoint origin; origin.x=240; origin.y=160; //NSLog(@"currentTouch Touch In Location In View:%F %F\n",touchLocationpoint.x,touchLocationpoint.y); //NSLog(@"currentTouch Touch previous Location In View:%F %F\n",PrevioustouchLocationpoint.x,PrevioustouchLocationpoint.y); CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint]; CGAffineTransform newTransform =CGAffineTransformScale(ViewRotationArrow.transform, 1, 1); CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x); CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint]; CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x); CGFloat newAngle = currentRotation- previousRotation; NSLog(@"currentRotation of x %F previousRotation %F\n",currentRotation,previousRotation); NSLog(@"Angle:%F\n",(temp1*180)/M_PI); temp1=temp1+newAngle; //NSLog(@"Angle:%F\n",(temp1*180)/M_PI); newTransform = CGAffineTransformRotate(newTransform, newAngle); [self animateView:ViewRotationArrow toPosition:newTransform]; } -(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint { CGPoint result; CGFloat x = secondPoint.x-firstPoint.x; CGFloat y = secondPoint.y-firstPoint.y; result = CGPointMake(x, y); return result; } -(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform { //animating the rotator arrow... [UIView setAnimationsEnabled:YES]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationCurve:UIViewAnimationCurveLinear]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:0.0750]; ViewRotationArrow.transform = newTransform; [UIView commitAnimations]; }
-(void)rotateView { //shape of eclipse CAShapeLayer* circle = [[CAShapeLayer alloc] init]; CGMutablePathRef path = CGPathCreateMutable(); CGRect ViewRect = CGRectMake(self.view.bounds.size.width/2.8, (self.view.bounds.size.height-self.view.bounds.size.width/2)/2, self.view.bounds.size.width/4, self.view.bounds.size.width/2); float midX = CGRectGetMidX(ViewRect); float midY = CGRectGetMidY(ViewRect); CGAffineTransform t = CGAffineTransformConcat( CGAffineTransformConcat( CGAffineTransformMakeTranslation(-midX, -midY), CGAffineTransformMakeRotation(-1.57079633/0.99)), CGAffineTransformMakeTranslation(midX, midY)); CGPathAddEllipseInRect(path, &t, ViewRect); circle.path = path; circle.frame = self.view.bounds; circle.fillColor = [UIColor clearColor].CGColor; circle.strokeColor = [UIColor greenColor].CGColor; circle.lineWidth = 3.0f; [self.view.layer addSublayer:circle]; CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.duration = 0.0f; animation.fromValue = [NSNumber numberWithFloat:0.0f]; animation.toValue = [NSNumber numberWithFloat:1.0f]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; [circle addAnimation:animation forKey:@"strokeEnd"]; // rotateView red color testView=[[UIView alloc]init]; testView.frame=CGRectMake(0, 0, 20, 20); testView.backgroundColor=[UIColor redColor]; testView.userInteractionEnabled=YES; testView.center=CGPathGetCurrentPoint(path); testView.transform = CGAffineTransformMakeRotation(1.57079633); [testView sizeToFit]; [self.view.layer addSublayer:testView.layer]; // view Animation CAKeyframeAnimation* ViewAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; ViewAnimation.duration = 15.0f; ViewAnimation.path = path; ViewAnimation.rotationMode = kCAAnimationRotateAuto; ViewAnimation.calculationMode = kCAAnimationCubicPaced; //ViewAnimation.removedOnCompletion = NO; [testView.layer addAnimation:ViewAnimation forKey:@"position"]; }