1

I have a complex issue. I am making a twister game for iOS. You can drag the arrow of the wheel with your finger. Now I wan't to make it spin when the user is swiping.

Let's say I slow spin the arrow then it should slowly move and at the end it should stop, or when the user swipes as fast as he can the arrow should spin as fast as possible.

Currently I have this code which makes the arrow draggable.

How can I do this animation?

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    gestureStartPoint = [touch locationInView:self.view];

    CGPoint startPoint = CGPointMake(arrowImage.center.x, arrowImage.center.y);

    CGPoint endPoint = CGPointMake(gestureStartPoint.x, gestureStartPoint.y);

    angleStartVal = ((((atan2((endPoint.y - startPoint.y) , (endPoint.x - startPoint.x)))*180)/M_PI)+90);

    timerStart = CFAbsoluteTimeGetCurrent();

}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];
    CGPoint currentPosition = [touch locationInView:self.view];

    CGPoint startPoint = CGPointMake(arrowImage.center.x, arrowImage.center.y);
    CGPoint endPoint = CGPointMake(currentPosition.x, currentPosition.y);

    angleVal = ((((atan2((endPoint.y - startPoint.y) , (endPoint.x - startPoint.x)))*180)/M_PI)+90);
    arrowImage.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(angleVal));

     //NSLog(@"angle: %f",angleVal);

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

}
Jordi Kroon
  • 2,607
  • 3
  • 31
  • 55
  • Did you give the UIPanGestureRecognizer a shot that I suggested below? I believe it's exactly what you need. – Ben Coffman Jan 29 '13 at 21:45
  • Hi, I have added an SO of my own trying to solve the same problem. I've managed to do it. All the code is in my question here... http://stackoverflow.com/questions/14632754/loop-uiscrollview-but-continue-decelerating I'll also add the link into my answer. – Fogmeister Jan 31 '13 at 19:39
  • Any update on this? I've provided an answer with all the code you need to do what you want. I even built the project to check it works. But you haven't commented or anything. – Fogmeister Feb 04 '13 at 08:53

2 Answers2

4

If you want this to decelerate until it comes to a stop then I would implement this by having an invisible scrollView to control it.

The UIScrollView already decelerates when swiped and you can control the deceleration speed.

The VC should be the UIScrollViewDelegate and make it an "infinite scroll view". i.e. when it scrolls to one end then the delegate puts it back to the other end.

Now you can apply the contentOffset amount in the x direction ti the rotation angle.

0% offset = 0 rotation 100% offset = 360 rotation

Now you're not trying to animate the rotation at all you're just taking the offset of the scrollView and applying that as a rotation to the needle.

TBH, you don't even need it to be invisible, just put nothing on it and place the scrollView over your needle.

i.e.

[--------SCROLL VIEW---------]  //scroll this
[--------NEEDLE VIEW---------]  //Use the scroll amount from the scroll view to apply rotation here.
[-COLORS and BODY PARTS VIEW-]  //Doesn't move
[-----VC  View---------------]  //Doesn't move

Apple has used a similar technique to this for several UIs.

EDIT

I have created this myself to test my method would work.

You can see the full code for the UIViewController to run this...

Loop UIScrollView but continue decelerating

The UIImageView is a square view with an arrow pointing upwards. The UIScrollView has the exact same frame as the UIImageView and sit on top of it.

Community
  • 1
  • 1
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 2
    This method is used in one of the WWDC 2012 sessions (I believe it was #223 - Enhancing user experience with scroll views) – Lance Feb 01 '13 at 00:00
  • I know I saw something similar in WWDC. I can't remember what it was controlling though? That's what gave me this idea, I did write this myself from scratch though :-D Ah yes, it was an open GL car game where you could scroll through the cars in your garage. – Fogmeister Feb 01 '13 at 00:06
1

to make the arrow image view move and turn at the same time I would embed the arrow image view in a view and use the CGAffineTransformMakeRotation like you are doing. Then move the view the arrow is embed in and rotate the imageview of arrow at the same time.

Then to make it rotate and or move faster as a person swipes I would look at the UIPanGestureRecognizer with velocityInView: to see how fast they are moving their finger and adjust animations accordingly.

 _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[self.someView addGestureRecognizer:_panGestureRecognizer];

-(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer{
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint velocity    = [recognizer velocityInView:recognizer.view];



if (recognizer.state == UIGestureRecognizerStateBegan) {
}
else if (recognizer.state == UIGestureRecognizerStateChanged) {
    CGPoint tempPoint;
    tempPoint = [recognizer locationInView:self.view];
    NSLog(@"point %f", tempPoint.y);
    NSLog(@"center %f", self.someview.center.y);

}
else if (recognizer.state == UIGestureRecognizerStateEnded) {
    CGPoint tempPoint;
    tempPoint = [recognizer locationInView:self.view];


}

}

Ben Coffman
  • 1,750
  • 1
  • 18
  • 26