Is it possible to draw Graphics with CGContext and save them into a NSMutableArray?

5.7k views Asked by At

At first I draw graphics:

    -(void)drawRect: (CGRect)rect{  

        //Circle
    circle = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(circle, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(circle,CGRectMake(10,10, 50, 50));

        //rectangle
    rectangle = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(rectangle, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(rectangle, CGRectMake(10, 10, 50, 50));

        //square 
    square = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(square, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(square, CGRectMake(100, 100, 25, 25));

        //triangle  
    triangle = UIGraphicsGetCurrentContext(); 
    CGContextSetFillColorWithColor(triangle, [UIColor darkGrayColor].CGColor);
    CGPoint points[6] = { CGPointMake(100, 200), CGPointMake(150, 250),
                              CGPointMake(150, 250), CGPointMake(50, 250),
                              CGPointMake(50, 250), CGPointMake(100, 200) };
    CGContextStrokeLineSegments(triangle, points, 6);

    }

And now I want to put the graphics into an Array:

-(void)viewDidLoad {

grafics = [[NSMutableArray alloc]initWithObjects: circle,rectangle,square,triangle];
[self.navigationItem.title = @"Shape"];
[super viewDidLoad];
}

The problem is, that I have to make a cast thereby the objects fit into this array. Another problem is that the UITableViewController does not load the array into the rows. There is nothing wrong with the tableview, but a failure with handling CGContext. What I am doing wrong?

2

There are 2 answers

2
Jiri On BEST ANSWER

drawRect: is a method on UIView used to draw the view itself, not to pre-create graphic objects.

Since it seems that you want to create shapes to store them and draw later, it appears reasonable to create the shapes as UIImage and draw them using UIImageView. UIImage can be stored directly in an NSArray.

To create the images, do the following (on the main queue; not in drawRect:):

1) create a bitmap context

UIGraphicsBeginImageContextWithOptions(size, opaque, scale);

2) get the context

CGContextRef context = UIGraphicsGetCurrentContext();

3) draw whatever you need

4) export the context into an image

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

5) destroy the context

UIGraphicsEndImageContext();

6) store the reference to the image

[yourArray addObject:image];

Repeat for each shape you want to create.

For details see the documentation for the above mentioned functions. To get a better understanding of the difference between drawing in drawRect: and in arbitrary place in your program and of working with contexts in general, I would recommend you read the Quartz2D Programming Guide, especially the section on Graphics Contexts.

2
zoul On

First, UIGraphicsGetCurrentContext returns CGContextRef, which is not an object and cannot be stored directly in a collection (edit: this is not really true, see the comments). Technically speaking you could wrap the context in an NSValue or turn it into an UIImage:

CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *img = [UIImage imageWithCGImage:imageRef];

The resulting UIImage is an object and can be stored in a collection just fine. But the code sample does not make sense in the big picture. The -drawRect: method is meant to draw your component, not create some graphics to be used later. And -viewDidLoad is a UIViewController method, not a UIView one. Could you edit the question and describe what you are trying to do?