CAShapeLayers 上的抗锯齿

3
我有一个自定义视图用于加载指示器,它由许多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;
}

4
CAShapeLayer文档中提到,“形状将被绘制抗锯齿,并且尽可能在映射到屏幕空间之前被映射以保留分辨率独立性。但是,应用于图层或其祖先的某些类型的图像处理操作(例如CoreImage滤镜)可能会强制在本地坐标空间中进行光栅化。”每当我只添加一个CAShapeLayer时,它总是抗锯齿,因此也许您可以分享一下您正在做什么(代码、屏幕快照等),以便我们找出问题所在。 - Rob
@Rob 我已经更新了屏幕截图和代码。 - psobko
两个圆都是抗锯齿的。右侧的圆看起来比左侧的圆更加锯齿,但很难确定因为它们的大小不同。你能够用完全相同的尺寸绘制它们吗(并分享你使用的radiuslineWidth值)?在画圆时,radius的微小变化(例如38与38.3)可以极大地改变抗锯齿的视觉效果,所以请确保radius值完全相同。 - Rob
顺便说一句,我发现在drawRect中使用Core Graphics调用进行渲染可以呈现出更好的结果(更平滑、更好的抗锯齿等)比CAShapeLayer技术。此外,如果您使用CAShapeLayer技术,我发现阴影半径小(例如0.5),并且shadowOffsetCGSizeZero可以使曲线变得足够柔和,从而使其看起来更加平滑。 - Rob
1个回答

2
您提供的图片正是我遇到的情况。我得到了粗圆圈。在我的情况下,代码位于drawRect方法内。问题在于,每次调用drawRect时,我都会添加一个CAShapeLayer作为我的视图的子层。
因此,对于任何发现类似情况的人,请跟踪您正在添加的CAShapeLayer或在drawRect中重新绘制之前清除所有内容。

这是我的问题。移除叠加的CAShapeLayers导致边缘在每次重绘时不会变得锯齿状。感谢Micho。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接