ios - 相邻的 CAShapeLayer 抗锯齿问题

标签 ios objective-c graphics core-animation quartz-graphics

我正在使用 CAShapeLayer 为饼图的每个切片绘制一个饼图。即使一个饼图切片的结束角度等于相邻切片的起始角度,如果切片之间的边界呈一定角度,抗锯齿也会导致每个切片之间出现底层背景颜色。

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

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

我尝试了尽可能多的 CALayer 属性,但很难找到这方面的更多信息。有什么想法吗?

更新:请参阅下面我的回答。

最佳答案

您可能无法让您的饼图切片边缘完全没有裂缝地相遇。最简单的解决办法就是不去尝试。

与其让饼图切片在边缘相交,不如让它们重叠。将第一个切片绘制为完整的圆盘:

first slice

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

second slice

然后将第三个切片画成一个完整的圆盘,除了前两个切片的适当区域:

third slice

等等:

fourth slice fifth slice

这是我的代码:

#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

关于ios - 相邻的 CAShapeLayer 抗锯齿问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20502369/

相关文章:

iphone - iOS:用于登录屏幕的表格样式 TextField?

ios - 重新加载 ViewController 时 GPUImageView 变黑

math - 如何检测开放网格3D模型的边界顶点?

html - 网络图片的颜色可以与其背后的颜色相反吗?

java - OpenGL (ES) -- 当新对象添加到 ArrayList 时,多边形会暂时消失

ios - 如果用户没有打开通知,如何获取 AppDelegate' didFinishLunchingWithOptions 处的通知 extradata(payloadData)

ios - 修改默认启动画面中的应用程序名称

objective-c - iPad 上的多个呈现 View Controller 和旋转

java - Objective-C 相当于 Java 枚举或 "static final"对象

ios - 如何通过在第一个选项卡中单击按钮导航到另一个选项卡栏项目?