How to paint on multiple CGLayers at the same time?

I would like to draw objects for two separate CGLayers from the same loop for

, but I don’t know how.

For example, I would like to draw three orange circles behind three blue circles, with orange circles on one layer and blue circles on the other. The following code will place each circle on top of the previous circle:

-(void) drawRect:(CGRect)rect {
    UIBezierPath *circle;
    for (int i = 1; i <= 3; i++) {
        // Create an orange circle
        circle = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(CGRectMake(i*50, 80, 50, 50), 0, 0)];
        circle.lineWidth = 4.0f;
        [[UIColor colorWithRed:1.0 green:0.75 blue:0 alpha:1.0] setFill];
        [[UIColor orangeColor] setStroke];
        [circle stroke];
        [circle fill];

        // Create a blue circle
        circle = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(CGRectMake(25 + i*50, 80, 50, 50), 0, 0)];
        circle.lineWidth = 4.0f;
        [[UIColor colorWithRed:0 green:0.5 blue:1.0 alpha:1.0] setFill];
        [[UIColor blueColor] setStroke];
        [circle stroke];
        [circle fill];
    }
}

      

Output from the code above

How do I change this so that the three orange circles are in orangeLayer

, which sits behind the three blue circles in blueLayer

? I assume it has something to do with saving and restoring contexts, but I can't wrap my head around it.

Many thanks!

PS: I understand that I can just draw using two for

inline lines to achieve the correct effect, but this example is for instructional purposes to learn about layers. Thank!

+3


source to share


2 answers


I am creating a custom UIView subclass and creating a makeCircleWithFrame function to draw a circle inside the view using UIGraphicsBeginImageContextWithOptions, I believe it will solve your main problem:

#import "circleView.h"
#import <math.h>

@implementation circleView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) return self;

    [self setupViews];

    return self;
}

- (void)awakeFromNib
{
    [self setupViews];
}

- (void)setupViews
{
    [self setBackgroundColor:[UIColor whiteColor]];


    for (int i = 1; i <= 6; i++) {

        UIColor *circleColor;

        //Math function just to set different colors for each circle
        if (fmodf(i, 2) == 0) {
            circleColor = [UIColor colorWithRed:1.0 green:0.75 blue:0 alpha:1.0];
        }
        else {
            circleColor = [UIColor colorWithRed:0 green:0.5 blue:1.0 alpha:1.0];
        }


        UIView *circleView = [self makeCircleWithFrame:(CGRectMake(10*i, 10*i, 100, 100)) andFillColor:circleColor];
        circleView.tag = i;
        NSLog(@"circle %i", i);
    }
}

- (UIView *)makeCircleWithFrame:(CGRect)rect andFillColor:(UIColor *)color {
    // declare UIimageView, not UIView
    UIImageView *customView = [[UIImageView alloc] init];
    customView.frame= self.bounds;

    // create a new contex to draw
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0);

    UIBezierPath *grayCircle = [UIBezierPath bezierPathWithOvalInRect:rect];

    grayCircle.lineWidth = 6;
    [color setFill];
    [[UIColor orangeColor] setStroke];
    [grayCircle stroke];
    [grayCircle fill];

    customView.image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    [self addSubview:customView];

    return customView;
}

      



Please give me feedback if you still have problems or need help.

0


source


for this purpose, you need to either draw blue or orange circles partially (depending on which one you want to see from above). You probably understand that there are only 2 possible options: a) orange layer on top 2) blue. I think if you want to group the circles by color (without using 1 layer per circle), you are better off: 1) use 1 layer to paint 2) store the BΓ©zier paths (which represent the circles) somewhere 3) draw the paths according to the order and the overlay you want.



0


source







All Articles