You're probably not going to be able to make your pie slice edges meet up exactly with no cracks. The simplest solution is not to try.
Instead of making your pie slices meet at the edges, make them overlap. Draw the first slice as a full disc:
Then draw the second slice as a full disc, except for the proper area of the first slice:
Then draw the third slice as a full disc, except for the proper area of the first two slices:
And so on:
Here's my code:
#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