3

I have a view in which I have multiple horizontal lines (like a horzontal dial). I want to animate the horizontal movement. It should look like this

EDIT:

Horizontal Animation

enter image description here

enter image description here

How can I do this? As far as I understood I can't use CoreAnimation. Furthermore I wan't to be able to simulate different kinds of speed. How would the updatemethod work? Do I change the draw time, or distance?

I know I could solve this with a scrollview, but I would prefer not to use it.

Thanks!

Jan
  • 1,827
  • 2
  • 16
  • 29
  • I don't fully understand what you are trying to do. Why wouldn't you be able to use Core Animation? – David Rönnqvist Nov 08 '14 at 10:31
  • Maybe I didn't understand Core Animation. As far as I understood it animates the movement of a view, and not within. My Idea is to display the edge of a dial and the lines move, when the dial is spun. Thus the lines have to always repeat within an unmoving area. – Jan Nov 08 '14 at 10:38
  • Could you include an image showing what you are trying to do (preferably more then one frame (to understand what is meant to animate)? – David Rönnqvist Nov 08 '14 at 15:45

1 Answers1

10

If I've understood what you are trying to do, then I see no reason why you shouldn't be able to do that using Core Animation.

If the pattern you are moving is as simple as that then you can use a line dash pattern on a CAShapeLayer to draw the pattern. I created my layer so that it gets the line width from the height of the bounds and the shape layer's path gets its start and end points from the bounds of the layer:

CAShapeLayer *lineLayer = [CAShapeLayer layer];
lineLayer.bounds = CGRectMake(0, 0, 200, 60);
lineLayer.position = self.view.center;

lineLayer.strokeColor = [UIColor blackColor].CGColor;
lineLayer.lineDashPattern = @[@5, @2, @2, @2, @2, @2, @2, @2, @2, @2];
lineLayer.lineWidth = CGRectGetHeight(lineLayer.bounds);

UIBezierPath *linePath = [UIBezierPath bezierPath];
[linePath moveToPoint:CGPointMake(0, CGRectGetMidY(lineLayer.bounds))];
[linePath addLineToPoint:CGPointMake(CGRectGetMaxX(lineLayer.bounds), CGRectGetMidY(lineLayer.bounds))];
lineLayer.path = linePath.CGPath;

[self.view.layer addSublayer:lineLayer];

That will produce the static drawing of the pattern. The line dash pattern in the code is the length of the alternating segments of where the line is shown and where it is not.

enter image description here

With the path drawn, I did the animation by altering the "phase" of the line dashes (shifting them in one direction or the other). To make it seem like the pattern is smoothly and continuously moving I created a linear, repeating animation that shifts the pattern by its full length:

NSNumber *totalDashLenght = [lineLayer.lineDashPattern valueForKeyPath:@"@sum.self"]; // KVC is awesome :)

CABasicAnimation *animatePhase = [CABasicAnimation animationWithKeyPath:@"lineDashPhase"];
animatePhase.byValue = totalDashLenght; // using byValue means that even if the layer has a shifted phase, it will shift on top of that.
animatePhase.duration = 3.0;
animatePhase.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animatePhase.repeatCount = INFINITY;

[lineLayer addAnimation:animatePhase forKey:@"marching ants"];

The animated line looks like this:

enter image description here

If you want different lines to animate at different speeds you change the duration of the animation. This value represents the time it takes to animate the shifting one full phase.

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • Wow so I totally didn't get Core Animation. Just wondering.. since I want to use it as a control, how do I move it underneath my finger? – Jan Nov 08 '14 at 18:16
  • You could probably use the `timeOffset` of the layer to control the timing of the animation (like in [this answer](http://stackoverflow.com/a/18683845/608157)). You would have to figure out the math to translate between dragging the finger and the phase of the animation. It would depend on the length of one phase and the duration of the animation. – David Rönnqvist Nov 08 '14 at 19:59