tags:

views:

1568

answers:

3

I have a view that I want to add some custom drawing to.

I know how to do this with a View that isn't connected to a Nib/Xib file - you write the drawing code in the -drawRect: method.

But if I init the view using

[[MyView alloc] initWithNibName:@"MyView" bundle:[NSBundle mainBundle]];

-drawRect: of course doesn't get called. I tried doing the below code in -viewDidLoad

CGRect rect = [[self view] bounds];

CGContextRef ref = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ref, 2.0);
CGContextSetRGBStrokeColor(ref, 1.0, 1.0, 1.0, 1.0);
CGContextSetRGBFillColor(ref, 0, 0, 0, 0);
CGContextAddRect(ref, CGRectMake(1, 1, rect.size.width - 10, rect.size.height - 10));
CGContextStrokePath(ref);
CGContextDrawPath(ref, kCGPathFillStroke);

but nothing get drawn. Any ideas?

+2  A: 

How about doing all the drawing in a simple subview and add it to the XIB view (in viewDidLoad)?

codelogic
+3  A: 
e.James
Hadn't thought of the subview. Will give it a go.
KiwiBastard
+2  A: 

I think the issue is that you're treating a view and its view controller as interchangeable. For example, there's no -[UIView initWithNibName:bundle:] method — that's a UIViewController method.

Furthermore, a view isn't really like a "canvas" for drawing. A view will be asked to draw itself; in general, it won't be drawn into from "outside."

So:

  1. Rename your subclass of UIViewController from MyView to MyViewController.

  2. Create a new UIView subclass named MyView.

  3. Add a -drawRect: method to your new MyView class that does the drawing you want.

  4. Finally, set the Custom Class of your view controller's view in Interface Builder to MyView using the Identity Inspector.

For example, you should be able to use this for your -[MyView drawRect:] implementation:

- (void)drawRect:(CGRect)rect {
    CGRect bounds = [[self view] bounds];

    CGContextRef ref = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(ref, 2.0);
    CGContextSetRGBStrokeColor(ref, 1.0, 1.0, 1.0, 1.0);
    CGContextSetRGBFillColor(ref, 0, 0, 0, 0);
    CGContextAddRect(ref, CGRectMake(1, 1, bounds.size.width - 10, bounds.size.height - 10));
    CGContextStrokePath(ref);
    CGContextDrawPath(ref, kCGPathFillStroke);
}

The drawing will be clipped to the update rectangle passed in.

Chris Hanson
Good point! I didn't notice that he was using the UIView as the controller itself
e.James
I don't think he's actually using a UIView subclass as a view controller. I suspect he subclassed UIViewController but named the subclass "MyView."
Chris Hanson
Yeah you're right the class is a subclass of UIViewController. It's not called MyView just put that there as a placeholder. Anyway thanks for the suggestion. Thinking about what you have written, I understand what I am doing wrong...
KiwiBastard