title: Animate CAGradientLayer horizontally only
body: <p>I'm trying to animate a CAGradientLayer (the gradient, and the frame), and when I animate the frame down to 0, it shrinks up to the upper left corner of the view, and I want it to just animate out horizontally. Right now it's animating to 0 both horizontally and vertically. </p>
  
  <p>Here's what the animation currently looks like:</p>
  
  <p><img src="https://i.stack.imgur.com/pT3Dn.gif" alt="Animating CAGradientLayer"></p>
  
  <p>What I want is for when it goes down to nothing, to just shrink horizontally ONLY, and remain the same height the entire time.</p>
  
  <p>Here's the code I'm currently using:</p>
  
  <pre><code>- (void)drawRect:(CGRect)rect
  {
  // Drawing code
  if (!gradientLayer) {
      gradientLayer = [CAGradientLayer layer];
      [gradientLayer setFrame:[self createRectForFrame:rect]];
      [gradientLayer setColors:@[(id)fromColor.CGColor, (id)toColor.CGColor]];
      [gradientLayer setStartPoint:CGPointMake(fillPct/100, 0.5)];
      [gradientLayer setEndPoint:CGPointMake(1.0, 0.5)];
      [self.layer addSublayer:gradientLayer];
  }
  else {
      [gradientLayer removeAllAnimations];
  
      [CATransaction begin];
  
      [CATransaction setAnimationDuration:ANIMATION_DURATION];
      CGRect newFrame = [self createRectForFrame:rect];
      CABasicAnimation *frameAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
      [frameAnimation setDuration:ANIMATION_DURATION];
      [frameAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
      [frameAnimation setFromValue:[NSValue valueWithCGRect:gradientLayer.bounds]];
      [frameAnimation setToValue:[NSValue valueWithCGRect:newFrame]];
      [frameAnimation setFillMode:kCAFillModeForwards];
      [frameAnimation setRemovedOnCompletion:NO];
      [gradientLayer setFrame:newFrame];
      [gradientLayer addAnimation:frameAnimation forKey:@"frame"];
  
      CGPoint startPoint = CGPointMake(MIN(fillPct/100, 0.99), 0.5);
      CABasicAnimation *startPointAnimation = [CABasicAnimation animationWithKeyPath:@"startPoint"];
      [startPointAnimation setDuration:ANIMATION_DURATION];
      [startPointAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
      [startPointAnimation setFromValue:[NSValue valueWithCGPoint:gradientLayer.startPoint]];
      [startPointAnimation setToValue:[NSValue valueWithCGPoint:startPoint]];
      [startPointAnimation setFillMode:kCAFillModeForwards];
      [startPointAnimation setRemovedOnCompletion:NO];
      [gradientLayer setStartPoint:startPoint];
      [gradientLayer addAnimation:startPointAnimation forKey:@"startPoint"];
  
      [CATransaction setCompletionBlock:^{
          [self updateInnerLabelTextColor];
      }];
  
      [CATransaction commit];
  }
  [self bringInnerLabelToFront];
  }
  
  - (CGRect)createRectForFrame:(CGRect)frame {
  if (fillPct == 0)
      return CGRectZero;
  else if (fillPct &gt;= 100)
      return frame;
  else
      return CGRectMake(frame.origin.x, frame.origin.y, frame.size.width * (fillPct / 100), frame.size.height);
  }
  </code></pre>
  
  <p>fillPct is the value the bar should be filled, between 0 and 100.</p>