6

I'm preparing my iPhone app to publish on iOS 5 GM and came across a bug with UIView. When I override the drawRect method on a subclass, the Simulator shows the desired result but when I try to test on an actual device, the drawRect override doesn't have any effect at all.

I even placed a logging statement inside a drawRect override and confirmed that it is being called.

Has anyone else noticed this problem?

Here's a override code I'm using:

- (void)drawRect:(CGRect)rect {
DebugLog( @"*** calling drawRect ***" );

CGContextRef context = UIGraphicsGetCurrentContext(); 

// draw the dark gray background
CGContextSetFillColor(context, [SkinManager getWhiteColor]);
CGContextFillRect(context, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height)); 

// draw the text field background in white
CGContextSetFillColor(context, [SkinManager getDarkGray]);
CGContextFillRect(context, CGRectMake(2.0, 2.0, rect.size.width - 4, rect.size.height - 4)); 

}

Here's the code for generating color

    +(const CGFloat*) getDarkGray {
        UIColor *color = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1];

        return [self getCGColor:color];
}

+(const CGFloat*) getCGColor: (UIColor*)color {
        CGColorRef colorref = [color CGColor];

        const CGFloat *components = CGColorGetComponents(colorref);

        return components;
}

Again, this code works perfectly in iOS 4.x and in the Simulator for iOS 5. The only place that is broken is iOS 5 Device.

Jay
  • 71
  • 1
  • 3
  • Please post your code, it's more likely there's a problem there than in iOS since it's so very basic that others would have encountered it as well if there really is a bug (our company has several iOS apps and we haven't seen any problems in this area). – DarkDust Oct 08 '11 at 20:53
  • 1
    Also, iOS 5 is still under NDA so you might want to go to the Dev-Forum. – Philipp Schlösser Oct 08 '11 at 21:06
  • I did post a question in the dev forum but so far no one has any answers. – Jay Oct 09 '11 at 00:08

3 Answers3

2

Use [self setNeedsDisplay];

The drawRect method is called only at init, so it can pass that if your object was inited previously and you need to "refresh" it.

j0k
  • 22,600
  • 28
  • 79
  • 90
Gh Florin
  • 61
  • 2
0

Instead of using rect in your code, try using self.bounds. Rect is the area that needs refreshing, not the entire area of your view.

EricS
  • 9,650
  • 2
  • 38
  • 34
  • 1
    Are you sure that drawRect is in a subclass and not a category? Overriding within categories doesn't always work on all versions of iOS. – EricS Oct 09 '11 at 00:39
  • Yes, it's a sub class. It's actually a subclass of a subclass. I'm pretty confident this is a bug since the simulator works correctly. – Jay Oct 09 '11 at 01:53
  • Possibly, but 99% of the time when you think something is a system/compiler bug it's not. drawRect is obviously used by a lot of classes, so a gaping bug in it is unlikely, although not impossible, especially since iOS 5 isn't shipping yet. The one area where I see a lot of differences between device and the simulator is when accidentally returning uninitialized structures from functions - the simulator tends to zero out values and the device does not, but that doesn't apply here. You aren't calling drawRect directly, are you? – EricS Oct 10 '11 at 12:11
  • Thinking about what I just said...Show the code for [SkinManager getWhiteColor] and [SkinManager getDarkGray]. I bet you're returning local variable references. – EricS Oct 10 '11 at 12:14
0

in iOS 5 drawRect: is not on some objects e.g. UINavigationBar. You have to conditionally use the new iOS 5 styling methods under these circumstances.

This question and this question might be useful for you.

Community
  • 1
  • 1
Robert
  • 37,670
  • 37
  • 171
  • 213
  • 1
    Not true; it merely says that it won't be called unless you're in a subclass. And the OP is referring to a `UIView`, not any of the views this applies to. – FeifanZ Oct 27 '11 at 00:56