0

So I have a pie chart/color wheel that I made using CAShapeLayer and UIBezierPath. The wheel can have a max of 8 sections. I need it so each section is a different color. I've tried setting up an array (colorsArray) with different colors and inserting into the CAShapeLayer's fillColor method but it just takes the last color in the colorsArray. Is there a way to make sure a different color is in each layer section that is created? I'm a little lost right now. Here is my code below. Thanks in advance.

 -(void) drawWheel {

CGPoint circleCenter = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);

//1 Create a view that we’ll put everything else inside.
container = [[UIView alloc] initWithFrame:self.frame];
container.backgroundColor = [UIColor whiteColor];
container.layer.cornerRadius = 100.0;
container.layer.borderColor = [UIColor blackColor].CGColor;
container.layer.borderWidth = 1.0;

CGFloat angleSize = 2*M_PI/numberOfSections;

for (int i = 0; i < numberOfSections; i++) {

    CAShapeLayer *slice = [CAShapeLayer layer];
    *************************************************
    UIColor * color = [UIColor blueColor];

    //THIS MAKES THE WHOLE THING One Color - the last color in the colorsArray

    for (int i = 0; i < self.colorsArray.count; i++) {

        color = [self.colorsArray objectAtIndex:i];
        slice.fillColor = (__bridge CGColorRef)(color);
    }

    *************************************************

    slice.strokeColor = [UIColor whiteColor].CGColor;
    slice.lineWidth = 3.0;

    CGPoint center = CGPointMake(100.0, 100.0);
    CGFloat radius = 100.0;
    CGFloat startAngle = angleSize * i;

    UIBezierPath *piePath = [UIBezierPath bezierPath];
    [piePath moveToPoint:center];
    [piePath addLineToPoint:circleCenter];
    [piePath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:startAngle + angleSize clockwise:YES];

    [piePath closePath]; // this will automatically add a straight line to the center
    slice.path = piePath.CGPath;
    int i = 0;
    i++;

    [container.layer addSublayer:slice];
}

//7 Adds the container to the main control.
container.userInteractionEnabled = NO;
[self addSubview:container];

//8 Initialize sectors
sectors = [NSMutableArray arrayWithCapacity:numberOfSections];
if (numberOfSections % 2 == 0) {
    [self buildSectorsEven];
} else {
    [self buildSectorsOdd];
}

}
dcotter
  • 312
  • 6
  • 22
  • What if you remove the inner for loop "for (int i = 0; i < self.colorsArray.count; i++) {" ? – Groot Jan 31 '16 at 08:51
  • [here](http://stackoverflow.com/questions/35090451/circular-uiview-with-multiple-coloured-border-working-like-a-pie-chart/35095005#35095005) i have an answer for a case similar to yours. Check the question, i guess it will help you. – meth Jan 31 '16 at 12:28
  • @meth Sorry I'm a little new to programming and don't fully know how to implement this example. Can I use the (void)drawInContext:(CGContextRef)ctx method when using UIBezierPath? The example show the use of CGContextAddArc to draw the arcs instead of addArcWithCenter method of UIBezierPath. – dcotter Jan 31 '16 at 16:37

1 Answers1

0

I figured it out. I took loop that goes through my colorArray. I assigned a variable of "UIColor *color" to the object at the index (i) that matches the number of sections in my for loop "color = [self.colorsArray objectAtIndex:i];" I then assigned the variable color to the slice's fillColor.

Snippet:

for (int i = 0; i < numberOfSections; i++) {

CAShapeLayer *slice = [CAShapeLayer layer];

UIColor *color;
color = [self.colorsArray objectAtIndex:i];
slice.fillColor = [UIColor colorWithCGColor:(__bridge CGColorRef _Nonnull)(color)].CGColor;

Full Code:

-(void) drawWheel {

CGPoint circleCenter = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);

//1 Create a view that we’ll put everything else inside.
container = [[UIView alloc] initWithFrame:self.frame];
container.backgroundColor = [UIColor whiteColor];
container.layer.cornerRadius = 100.0;
container.layer.borderColor = [UIColor blackColor].CGColor;
container.layer.borderWidth = 1.0;

CGFloat angleSize = 2*M_PI/numberOfSections;

for (int i = 0; i < numberOfSections; i++) {

    CAShapeLayer *slice = [CAShapeLayer layer];

    UIColor *color;
    color = [self.colorsArray objectAtIndex:i];

    slice.strokeColor = [UIColor whiteColor].CGColor;
    slice.lineWidth = 3.0;
    slice.fillColor = [UIColor colorWithCGColor:(__bridge CGColorRef _Nonnull)(color)].CGColor;
    CGPoint center = CGPointMake(100.0, 100.0);
    CGFloat radius = 100.0;
    CGFloat startAngle = angleSize * i;

    UIBezierPath *piePath = [UIBezierPath bezierPath];
    [piePath moveToPoint:center];
    [piePath addLineToPoint:circleCenter];
    [piePath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:startAngle + angleSize clockwise:YES];
    [piePath closePath]; // this will automatically add a straight line to the center
    slice.path = piePath.CGPath;

    [container.layer addSublayer:slice];

}

//7 Adds the container to the main control.
container.userInteractionEnabled = NO;
[self addSubview:container];

//8 Initialize sectors
sectors = [NSMutableArray arrayWithCapacity:numberOfSections];
if (numberOfSections % 2 == 0) {
    [self buildSectorsEven];
} else {
    [self buildSectorsOdd];
}

}
dcotter
  • 312
  • 6
  • 22