Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UIView's drawRect never called if initial frame is CGRectZero

Tags:

ios

uiview

I've got a pretty simple custom subclass of UIView:

#import "BarView.h"
#import <QuartzCore/QuartzCore.h>

@implementation BarView

@synthesize barColor;

- (void)drawRect:(CGRect)rect
{
    NSLog(@"drawRect");
    // Draw a rectangle.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, self.barColor.CGColor);
    CGContextBeginPath(context);
    CGContextAddRect(context, self.bounds);
    CGContextFillPath(context);
}

- (void)dealloc
{
    self.barColor = nil;

    [super dealloc];
}

@end

If I call initWithFrame:rect on this class with some non-zero rect, it works fine; but when I call initWithFrame:CGRectZero, drawRect is -never- called, even after I modify the view's frame to a non-zero rect.

I certainly understand why a view with a zero frame would never have its drawRect: called, but why is it never called even after the frame is changed?

like image 607
Greg Maletic Avatar asked May 27 '11 18:05

Greg Maletic


2 Answers

A quick look at the Apple docs says this

Changing the frame rectangle automatically redisplays the view without calling its drawRect: method. If you want UIKit to call the drawRect: method when the frame rectangle changes, set the contentMode property to UIViewContentModeRedraw.

This is in the documentation for the frame property:
https://developer.apple.com/documentation/uikit/uiview/1622621-frame?language=objc

If you want the view to redraw, just call setNeedsDisplay on it and you should be fine (or, as the docs say, you can set it to UIViewContentModeRedraw, but it is up to you)

like image 54
Scott Rice Avatar answered Nov 12 '22 17:11

Scott Rice


In Swift 5

override init(frame: CGRect) {
      super.init(frame: frame)

      contentMode = UIView.ContentMode.redraw
like image 23
dengApro Avatar answered Nov 12 '22 19:11

dengApro