Пользовательский UIView drawRect никогда не вызывается, если начальный кадр CGRectZero
У меня есть довольно простой пользовательский подкласс 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
Если я вызову initWithFrame: rect для этого класса с некоторым ненулевым прямоangularьником, он работает нормально; но когда я вызываю initWithFrame: CGRectZero, drawRect вызывается никогда, даже после того, как я изменяю рамку вида на ненулевой прямоangularьник.
Я, конечно, понимаю, почему представление с нулевым фреймом никогда не будет вызывать drawRect: call, но почему оно никогда не вызывается даже после изменения фрейма?
Ответы
Ответ 1
Быстрый взгляд на документы Apple говорит об этом
Изменение прямоangularьника рамки автоматически переотображает представление, не вызывая его drawRect: метод. Если вы хотите, чтобы UIKit вызывал метод drawRect: при изменении прямоangularьника рамки, установите для свойства contentMode значение UIViewContentModeRedraw.
Это в документации по свойству фрейма:
https://developer.apple.com/documentation/uikit/uiview/1622621-frame?language=objc
Если вы хотите перерисовать представление, просто вызовите для него setNeedsDisplay, и все будет в порядке (или, как говорят документы, вы можете установить для него значение UIViewContentModeRedraw, но это зависит от вас)
Ответ 2
В Swift 5
override init(frame: CGRect) {
super.init(frame: frame)
contentMode = UIView.ContentMode.redraw