0
votes

I've made a UIView subclass called MiniView.

I try adding it to my viewController as follows:

@interface SomeViewController ()

@property (strong, nonatomic) MiniView *miniView;

@end

- (void)viewDidLoad
        {
        [super viewDidLoad];

        self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
        _miniView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:_miniView];
    }

The MiniView class looks like this:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    NSLog(@"DRAW RECT");
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIColor * redColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
    CGContextSetFillColorWithColor(context, redColor.CGColor);
    CGContextFillRect(context, self.bounds);
}

But drawRect never gets called, unless I explicity call it, from within the setNeedsLayout method. It also doesn't draw anything. I've tried just adding a UIImageView in the drawRect method, and this appears fine. But the above code produces nothing.

I also get the error:

: CGContextSetFillColorWithColor: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

If I print a log statement in the drawRect method and output the 'rect' values, it's correct at 200 x 200, so I don't know why the context is 0x0.

So one problem is that drawRect is never called, and the other problem is that if I call it explicitly, nothing is displayed...

4
Ah, I just realised what I was doing wrong - I had redefined the setNeedsDisplay method in my MiniView class to NSLog something. So it wasn't behaving correctly. I put a call to [super setNeedsDisplay] and now it works slaps headSmikey

4 Answers

1
votes

You probably need to call setNeedsDisplay on your custom UIView subclass:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
    _miniView.backgroundColor = [UIColor blackColor];
    [_miniView setNeedsDisplay];    // Added this
    [self.view addSubview:_miniView];
}

This is basically a prod to tell the system your UIView needs to be redrawn. See the docs for more info.

1
votes

Posting as a separate answer as requested:

The actual problem was that I had redefined the setNeedsDisplay method in the MiniView class, like so:

- (void)setNeedsDisplay
{
    NSLog(@"Redrawing info: %@", [_info description]);
}

Because I had neglected to make a call to [super setNeedsDisplay], drawRect was never being called and nothing was drawing. So this fixed it:

- (void)setNeedsDisplay
{
    [super setNeedsDisplay];
    NSLog(@"Redrawing info: %@", [_info description]);
}
0
votes

Never call drawRect explicity, try this:

- (void)viewDidLoad
        {
        [super viewDidLoad];

        self.miniView = [[MiniView alloc] initWithFrame:CGRectMake(20.f, 20.f, 200.f, 200.f)];
        _miniView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:_miniView];

        [_miniView setNeedsDisplay];
    }
0
votes

Well in your drawrect method include this line:-

        [super drawRect:rect];