7

I can't figure out what the problem is here. I have a very simple UIViewController with a very simple viewDidLoad method:

-(void)viewDidLoad {

    NSLog(@"making game view");
    GameView *v = [[GameView alloc] initWithFrame:CGRectMake(0,0,320,460)];

    [self.view addSubview:v];

    [super viewDidLoad];
}

And my GameView is initialized as follows:

@interface GameView : UIView {

and it simply has a new drawRect method:

- (void)drawRect:(CGRect)rect
{

    [super drawRect:rect];

    NSLog(@"drawing");
}

In my console, I see "making game view" being printed, but "drawing" never is printed. Why? Why isn't my drawRect method in my custom UIView being called. I'm literally just trying to draw a circle on the screen.

CodeGuy
  • 28,427
  • 76
  • 200
  • 317

4 Answers4

12

Have you tried specifying the frame in the initialization of the view? Because you are creating a custom UIView, you need to specify the frame for the view before the drawing method is called.

Try changing your viewDidLoad to the following:

NSLog(@"making game view");
GameView *v = [[GameView alloc] initWithFrame:CGRectMake(0,0,320,460)];


if (v == nil)
    NSLog(@"was not allocated and/or initialized");

[self.view addSubview:v];

if (v.superview == nil)
    NSLog(@"was not added to view");

[super viewDidLoad];

let me know what you get.

Eytan
  • 1,825
  • 17
  • 24
  • how can I override the init method to do this? what is the proper method heading for that? – CodeGuy Jun 07 '11 at 21:13
  • I tried making it like this: GameView *v = [[GameView alloc] initWithFrame:CGRectMake(0,0,320,460)]; but it still didn't work – CodeGuy Jun 07 '11 at 21:14
  • Have you made any other customizations? – Eytan Jun 07 '11 at 21:23
  • Thanks for this @Eytan. Something happens when calling `[super initWithFrame:...]` that enables `drawRect`. I was overriding an init statement and setting the frame there. If I changed the `self = [super init]` to `self = [super initWithFrame:CGRectMake(1,1,1,1)]`, it would work. Now I just override initWithFrame to make it more transparent. – HotFudgeSunday Jan 08 '15 at 14:56
0

Check if your view is being displayed. If a view is not currently on screen, drawRect will not be getting called even if you add the view to its superview. A possibility is that your view is blocked by the some other view.

And as far as I know, you don't need to write [super drawRect];

Note that even if viewDidLoad is called on a view controller it doesn't necessarily indicate the view controller's view is displayed on screen. Example: Assume a view controller A has an ivar where a view controller B is stored and view controller A's view is currently displayed. Also assume B is alloced and inited. Now if some method in A causes B's view to be accessed viewDidLoad in B will be called as a result regardless whether it's displayed.

0

If you're using a CocoaTouch lib or file you may need to override the initWithCoder method instead of viewDidLoad.

Objective-C:

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        //Do Stuff Here
    }
    return self;
}
Zack Weiner
  • 664
  • 4
  • 14
0

I had a view that was offscreen, that I would load onscreen and then redraw. However, while cleaning up auto-layout constraints in XCode, it decided my offscreen view should have a frame (0,0,0,0) (x,y,w,h). And with a (0,0) size, the view would never load.

Make sure your NSView has a nonzero frame size, or else drawRect will not be called.

jtf
  • 125
  • 7