Cory D. Wiles
Cory D. Wiles

Reputation: 556

How do I correctly position an animated CAShapeLayer

I'm animating the end stroke of a CAShapeLayer, but the position is incorrect and I can't figure out what I'm doing wrong. The frame is correct, but when I try and adjust the position I can't get it to "fill" the frame's width of the view. I've tried to adjust the _maskLine's position, but my approaches have failed thus far.

The frame of the view is: 10, 10, 50, 100

See image (the red shape layer should be "shifted" over 10 pts.

enter image description here

// layer setup in initWithFrame

_maskLine = [CAShapeLayer layer];

_maskLine.lineCap   = kCALineCapButt;
_maskLine.fillColor = [[UIColor whiteColor] CGColor];
_maskLine.lineWidth = frame.size.width;
_maskLine.strokeEnd = 0.0;
_maskLine.frame     = self.bounds;

[self.layer addSublayer:_maskLine];

self.clipsToBounds      = YES;
self.layer.cornerRadius = 2.0f;


// animation method logic

UIBezierPath *progressline = [UIBezierPath bezierPath];

NSUInteger randomInt = arc4random() % (NSUInteger)self.maxMeterHeight;

self.meterHeight = (randomInt / self.maxMeterHeight);

[progressline moveToPoint:CGPointMake(CGRectGetMidX(self.frame), CGRectGetHeight(self.frame))];
[progressline addLineToPoint:CGPointMake(CGRectGetMidX(self.frame), (1 - self.meterHeight) * CGRectGetHeight(self.frame))];

[progressline setLineWidth:1.0];
[progressline setLineCapStyle:kCGLineCapSquare];

self.maskLine.path        = progressline.CGPath;
self.maskLine.strokeColor = [UIColor redColor].CGColor;
self.maskLine.frame       = self.bounds;

NSLog(@"mask frame: %@", NSStringFromCGRect(self.maskLine.frame));

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

pathAnimation.duration       = 0.35;
pathAnimation.autoreverses   = YES;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue      = @0.0f;
pathAnimation.toValue        = @1.0f;
pathAnimation.cumulative     = YES;

[self.maskLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"];

[CATransaction commit];

self.maskLine.strokeEnd = 1.0;

Upvotes: 1

Views: 861

Answers (1)

Cory D. Wiles
Cory D. Wiles

Reputation: 556

The "fix" was changing these lines

[progressline moveToPoint:CGPointMake(CGRectGetMidX(self.frame), CGRectGetHeight(self.frame))];
[progressline addLineToPoint:CGPointMake(CGRectGetMidX(self.frame), (1 - self.meterHeight) * CGRectGetHeight(self.frame))];

to:

[progressline moveToPoint:CGPointMake(self.frame.size.width / 2, CGRectGetHeight(self.frame))];
[progressline addLineToPoint:CGPointMake(self.frame.size.width / 2, (1 - self.meterHeight) * CGRectGetHeight(self.frame))];

Upvotes: 1

Related Questions