A custom UIView drawRect is never called if the start frame is CGRectZero

I have 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 for this class with some non-zero rectangle, it works fine; but when I call initWithFrame: CGRectZero, drawRect is never called, even after I change the view frame to a non-zero rectangle.

Of course, I understand why a view with a zero frame will never call drawRect: call, but why will it never be called even after changing the frame?

+10
source share
2 answers

A quick look at Apple docs says it

Changing the rectangle border of a frame automatically reimages the view without calling its drawRect: method. If you want UIKit to call the drawRect: method when changing the rectangle border of the frame, set the contentMode property to UIViewContentModeRedraw.

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

If you want to redraw the view, just call setNeedsDisplay for it, and everything will be fine (or, as the docs say, you can set it to UIViewContentModeRedraw, but it's up to you)

+28
source

In Swift 5

 override init(frame: CGRect) { super.init(frame: frame) contentMode = UIView.ContentMode.redraw 
0
source

All Articles