简体   繁体   English

如果初始帧为 CGRectZero,则不会调用自定义 UIView 的 drawRect

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

I've got a pretty simple custom subclass of UIView:我有一个非常简单的 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;如果我用一些非零矩形在这个 class 上调用 initWithFrame:rect,它工作正常; but when I call initWithFrame:CGRectZero, drawRect is -never- called, even after I modify the view's frame to a non-zero rect.但是当我调用 initWithFrame:CGRectZero 时,drawRect 永远不会被调用,即使在我将视图的框架修改为非零矩形之后也是如此。

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?我当然理解为什么一个零帧的视图永远不会调用它的 drawRect:,但是为什么即使在帧改变之后它也不会被调用呢?

A quick look at the Apple docs says this快速浏览一下 Apple 文档就说明了这一点

Changing the frame rectangle automatically redisplays the view without calling its drawRect: method.更改框架矩形会自动重新显示视图,而无需调用其 drawRect: 方法。 If you want UIKit to call the drawRect: method when the frame rectangle changes, set the contentMode property to UIViewContentModeRedraw.如果希望 UIKit 在框架矩形发生变化时调用 drawRect: 方法,请将 contentMode 属性设置为 UIViewContentModeRedraw。

This is in the documentation for the frame property:这是在框架属性的文档中:
https://developer.apple.com/documentation/uikit/uiview/1622621-frame?language=objc 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)如果您希望重绘视图,只需在其上调用 setNeedsDisplay 就可以了(或者,正如文档所说,您可以将其设置为 UIViewContentModeRedraw,但这取决于您)

In Swift 5在 Swift 5

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

      contentMode = UIView.ContentMode.redraw

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM