【发布时间】:2014-03-28 18:24:26
【问题描述】:
我有一个加载指示器的自定义视图,它由多个 CAShapeLayers 组成,我在其上执行各种动画来表示各种状态。在 init 方法中,我创建了许多形状图层并将它们作为子图层添加到视图的图层中。我遇到的问题是我正在绘制的形状边缘非常粗糙,并且似乎没有抗锯齿。我已经从这里的类似答案中尝试了很多东西,但我似乎无法对形状进行抗锯齿处理。之前没遇到过这个问题直接在drawRect画图。
我有什么遗漏或者有更好的方法来完成我想做的事情吗?
更新:以下是绘制形状的比较:
在左侧,我正在使用此代码在layoutSubviews 中绘制:
CGFloat lineWidth = 2.5f;
CGFloat radius = (self.bounds.size.width - lineWidth)/2;
CGPoint center = CGPointMake(CGRectGetWidth(self.frame)/2, CGRectGetHeight(self.frame)/2);
CGFloat startAngle = - ((float)M_PI / 2);
CGFloat endAngle = (2 * (float)M_PI) + startAngle;
UIBezierPath *trackPath = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:startAngle
endAngle:endAngle
clockwise:YES];
self.trackLayer.path = trackPath.CGPath;
self.trackLayer.lineWidth = lineWidth;
在右侧,我正在从awakeFromNib 调用一个单独的方法:
-(void)awakeFromNib
{
....
self.trackLayer = [self trackShape]
[self.layer addSublayer:self.trackLayer];
}
-(CAShapeLayer*)trackShape
{
float start_angle = 2*M_PI*-M_PI_2;
float end_angle = 2*M_PI*1-M_PI_2;
float minSize = MIN(self.frame.size.width, self.frame.size.height);
float radius = (minSize-_strokeWidth)/2 -4;
CGPoint center = CGPointMake(self.frame.size.width/2,self.frame.size.height/2);
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:start_angle
endAngle:end_angle
clockwise:YES].CGPath;
circle.strokeColor = self.trackColor.CGColor;
circle.fillColor = nil;
circle.lineWidth = (_strokeWidth == -1.0) ? minSize * _strokeWidthRatio
: _strokeWidth;
circle.rasterizationScale = [[UIScreen mainScreen] scale];
return circle;
}
【问题讨论】:
-
CAShapeLayer文档说,“形状将被抗锯齿绘制,并且尽可能在光栅化之前将其映射到屏幕空间以保持分辨率独立性。但是,某些类型的图像处理操作,例如 CoreImage 过滤器,应用于图层或其祖先可能会强制在局部坐标空间中进行光栅化。”每当我添加CAShapeLayer时,它总是会消除锯齿,所以也许您可以分享您正在做的事情(代码、屏幕快照等),以便我们弄清楚发生了什么。 -
@Rob 我已经更新了截图和代码。
-
两个圆圈实际上都是抗锯齿的。右边的那个看起来比右边的那个锯齿状,但真的很难说,因为它们的尺寸不同。你能画出完全相同的尺寸吗(并分享你使用的
radius和lineWidth值)?对于圆圈,radius中的细微变化(例如 38 与 38.3)会从根本上改变抗锯齿的视觉效果,因此请确保radius的值完全相同。 -
顺便说一句,我发现通过
drawRect中的Core Graphics 调用进行渲染可以提供比CAShapeLayer技术更好的结果(更平滑、更好的抗锯齿等)。此外,如果您使用CAShapeLayer技术,我发现半径较小(例如0.5)的阴影和CGSizeZero的shadowOffset可以柔化曲线,使其看起来更平滑。跨度>
标签: objective-c core-graphics antialiasing