简体   繁体   中英

How to draw to multiple CGLayers at the same time?

I'd like to draw objects to two separate CGLayers from within the same for loop, but am unsure how to do this.

For example, I'd like to draw three orange circles behind three blue circles, with the orange circles in one layer, and the blue circles in another. 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];
    }
}

从上面的代码输出

How would I modify this so that the three orange circles would end up in an orangeLayer that sits behind the three blue circles in a blueLayer ? I imagine this has something to do with saving and restoring contexts, but I can't really wrap my head around it.

Thanks so much!

PS: I realize that I can simply draw using two for loops inline to achieve the right effect, but this example is for instructional purposes to learn layering. Thanks!

I build a custom subclass of UIView, and create a function makeCircleWithFrame to draw a circle inside a 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 a feedback if you still having problems or need anymore help.

for that purpose you need to either draw the blue or the orange circles partially (depends on which one you want to be on top). You probably understand that there are only 2 possible options: a) the orange layer is on top 2) the blue one is. I think, if you want to group the circles by color (without using 1 layer per circle), you'd better: 1) use 1 layer for drawing 2) store Bezier paths (which represent circles) somewhere 3) draw the paths in accordance to the order and overlaying you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM