title: Core Animation speed
body: <p>I'd like to create animation similar to swiping in menus of iPhone. That means if you swipe enough, animation takes you to new page, but if you swipe just a little animation takes you back on starting page after finishing swipe gesture.</p>
  
  <p>So far, I have swipe recognizer which listens to position of finger on screen and follows the movement of finger. Animation looks at the end of gesture whether finger moved more than 1/3 of screen width and decides whether to proceed to its end or go back to beginning.</p>
  
  <pre><code>- (void)panGestureHandler:(UIPanGestureRecognizer*)recognizer
  {
      if (recognizer.state == UIGestureRecognizerStateEnded)
      {
          //if our gesture was enough to let animation roll to its end
          if (fabsf(translation.x) &gt; CGRectGetWidth(self.view.frame) * 0.33)
          {
              [self finishLayer:categoryControllerMain.view.layer animation:menuOpenSwipeAnimateMoveLeft withForward:NO];
          }
          //finger movement was below .33% of screen width so animate to initial state
          else
          {
              [self finishLayer:categoryControllerMain.view.layer animation:menuOpenSwipeAnimateMoveLeft withForward:NO];
  
          }
      }
      else if (recognizer.state == UIGestureRecognizerStateChanged)
      {
          //We put layer speed to zero so we can control animation with timeoffset in relation to finger pan movement
          categoryControllerMain.view.layer.speed = 0.0;
          [categoryControllerMain.view.layer addAnimation:menuOpenSwipeAnimateMoveLeft forKey:@"menuOpenMoveLeft"];
          categoryControllerMain.view.layer.timeOffset = fabs(translation.x / CGRectGetWidth(self.view.frame));
      }
  }
  </code></pre>
  
  <p>And this is the method which says to animation whether to move towards its end or beginning, according to finger amount movement. If I just swiped a bit, animation continues with <code>speed = -1;</code>, i.e. it starts going backwards, but when it gets to its end, or in this case beginning, all layers just disappear. Here is not the case of <code>presentationLayer</code>, because when animation ends, all the layers should be at that exact point, because that is their initial point. Instead, all the layers are gone, and when I try to swipe again, they appear on their correct locations.</p>
  
  <pre><code>- (void)finishLayer:(CALayer*)layer animation:(CAKeyframeAnimation*)animation withForward:(BOOL)shouldGoForward
  {
  
      pan.enabled = NO;
      if (shouldGoForward)
      {
          //animation continues
          CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
          layer.timeOffset = 0.0;
          layer.beginTime = 0.0;
          CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
          layer.beginTime = timeSincePause;
          layer.speed = 1.0;
      }
      else
      {
          //we want to take it back. This is where strange things happen. Perhaps timeoffset is not right
          layer.timeOffset = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
          layer.beginTime = CACurrentMediaTime();
          layer.speed = -1;
      }
  }
  </code></pre>
  
  <p>A final consideration: If my animations were linear, then I could create another animation for every animation from beginning, calculate where to start and make it appear as one animation. But my animations have <code>CAMediaTimingFunction</code>s which don't allow me to calculate exact position in opposite animation.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>The question is the following: how to perform core animation with <code>speed = -1</code> so that when animations rolls backwards, all of layers/views stay visible on screen?</p>
  
  <p>Thanks in advance</p>