我正在尝试通过添加具有不同笔触颜色的CAShapeLayer
来创建圆形动画:
UIView *view = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
[self.view addSubview:view];
view.backgroundColor = [UIColor redColor];
[self addCircleAnimationTo:view direction:YES];
- (void)addCircleAnimationTo:(UIView *)view direction:(BOOL)direction {
CGFloat animationTime = 3;
// Set up the shape of the circle
int radius = view.frame.size.width/2;
CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius)
cornerRadius:radius].CGPath;
// Center the shape in view
circle.position = CGPointMake(radius,
radius);
circle.bounds = view.bounds;
// Configure the apperence of the circle
circle.fillColor = [UIColor clearColor].CGColor;
// switch color
circle.strokeColor = (direction) ? [UIColor blueColor].CGColor : [UIColor whiteColor].CGColor;
circle.lineWidth = 5;
circle.lineJoin = kCALineJoinBevel;
circle.strokeStart = .0;
circle.strokeEnd = 1.;
// Configure animation
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = animationTime;
drawAnimation.repeatCount = 1;
// Animate from no part of the stroke being drawn to the entire stroke being drawn
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:1.];
// Experiment with timing to get the appearence to look the way you want
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
// Add to parent layer
[view.layer addSublayer:circle];
// Add the animation to the circle
[circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((animationTime-0.1) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self addCircleAnimationTo:view direction:!direction];
});
}
我想知道为什么在设置白色动画时为什么能看到蓝色,以及如何摆脱这种奇怪的蓝色边框:
最佳答案
抗锯齿是导致问题的原因
当白色CAShapeLayer
在蓝色上绘制时,边缘将与抗锯齿创建的先前边缘融合在一起。
唯一真正的解决方案是在设置动画时从白色下面清除蓝色。 可以通过使上一层从strokeStart
到0.0
的上一层的1.0
属性动画来实现。通过更改drawAnimation
,您应该能够为此重新使用keyPath
。例如,将dispatch_after
更改为:
- (void)addCircleAnimationTo:(UIView *)view direction:(BOOL)direction {
// Insert your previous animation code, where drawAnimation is defined and added to the circle layer.
drawAnimation.keyPath = @"strokeStart"; // Re-use the draw animation object, setting it to animate strokeStart now.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((animationTime-0.1) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self addCircleAnimationTo:view direction:!direction];
[circle addAnimation:drawAnimation forKey:@"(un)drawCircleAnimation"]; // Sets the previous layer to animate out
});
}
这样,可以从蓝色层清除抗锯齿边缘融合,使白色层获得漂亮而干净的抗锯齿。 动画制作完成后,别忘了删除图层!
另一个可能的解决方案是增加白色层的笔触宽度,以便在蓝色层的边缘融合上笔触,但是我想这会产生不希望的效果。您也可以禁用抗锯齿功能,但这在圈子中看起来会很可怕。
关于ios - CAShapeLayer渲染问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34943808/