相邻的CAShapeLayer抗锯齿问题

Aar*_*ron 13 graphics core-animation objective-c quartz-graphics ios

我正在为饼图的每个切片使用CAShapeLayer绘制饼图.即使当一个扇形切片的结束角度等于相邻切片的起始角度时,如果切片之间的边界处于一个角度,则抗锯齿​​导致下面的背景颜色出现在每个pice切片之间.

http://i.stack.imgur.com/Qdu8d.png

我想在仍然使用抗锯齿的同时消除切片之间的微小间隙,这样得到的饼图仍然看起来很光滑.从概念上讲,似乎有一种方法可以将抗锯齿应用于整个CALayer,并且在绘制完所有饼图切片之后它是饼图切片子层,这样做就可以了.馅饼切片会相互抗锯齿而不是进入背景.

我已经玩过尽可能多的CALayer属性,并且我很难找到更多关于此的信息.有任何想法吗?

更新:请参阅下面的答案.

rob*_*off 9

你可能无法让你的馅饼切片边缘完全没有裂缝.最简单的解决方案是不要尝试.

而不是让你的饼切片在边缘相遇,使它们重叠.将第一个切片绘制为完整的光盘:

第一片

然后将第二个切片绘制为完整的光盘,除了第一个切片的适当区域:

第二片

然后将第三个切片绘制为完整的光盘,除了前两个切片的适当区域:

第三片

等等:

第四片 第五片

这是我的代码:

#import "PieView.h"

@implementation PieView {
    NSMutableArray *slices;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self layoutSliceLayers];
}

- (void)layoutSliceLayers {
    if (slices == nil) {
        [self createSlices];
    }
    [slices enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [self layoutSliceLayer:obj index:idx];
    }];
}

static const int kSliceCount = 5;

- (void)createSlices {
    slices = [NSMutableArray arrayWithCapacity:kSliceCount];
    for (int i = 0; i < kSliceCount; ++i) {
        [slices addObject:[self newSliceLayerForIndex:i]];
    }
}

- (CAShapeLayer *)newSliceLayerForIndex:(int)i {
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.fillColor = [UIColor colorWithWhite:(CGFloat)i / kSliceCount alpha:1].CGColor;
    [self.layer addSublayer:layer];
    return layer;
}

- (void)layoutSliceLayer:(CAShapeLayer *)layer index:(int)index {
    layer.position = [self center];
    layer.path = [self pathForSliceIndex:index].CGPath;
}

- (CGPoint)center {
    CGRect bounds = self.bounds;
    return CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
}

- (UIBezierPath *)pathForSliceIndex:(int)i {
    CGFloat radius = [self radius];
    CGFloat fudgeRadians = 5 / radius;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero
        radius:radius startAngle:2 * M_PI * i / kSliceCount
        endAngle:2 * M_PI clockwise:YES];
    [path addLineToPoint:CGPointZero];
    [path closePath];
    return path;
}

- (CGFloat)radius {
    CGSize size = self.bounds.size;
    return 0.9 * MIN(size.width, size.height) / 2;
}

@end
Run Code Online (Sandbox Code Playgroud)


Aar*_*ron 7

更新: Rob的答案非常好,但可能导致其他抗锯齿问题.我最终通过沿每个扇形切片的端角绘制1pt宽的径向线来"填充"间隙,每条线与相邻切片的颜色相同.这些线条绘制的z索引低于饼图切片,因此它们位于下方.这是他们看起来没有在顶部绘制的饼图:

填料线没有切片.

这是最终产品:

最终结果是下面的线条和顶部的切片.