【问题标题】:Need to override drawrect if your UIView is merely a container?如果您的 UIView 只是一个容器,是否需要覆盖 drawrect?
【发布时间】:2010-06-03 00:34:33
【问题描述】:

根据 Apple 的文档,“如果子类是其他视图的容器,则子类不需要覆盖 -[UIView drawRect:]。”

我有一个自定义 UIView 子类,它实际上只是其他视图的容器。然而,包含的视图并没有被绘制出来。下面是设置自定义 UIView 子类的相关代码:

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        // Consists of both an "on" light and an "off" light. We flick between the two depending upon our state.
        self.onLight = [[[LoyaltyCardNumberView alloc] initWithFrame:frame] autorelease];
        self.onLight.backgroundColor = [UIColor clearColor];
        self.onLight.on = YES;
        [self addSubview:self.onLight];

        self.offLight = [[[LoyaltyCardNumberView alloc] initWithFrame:frame] autorelease];
        self.offLight.backgroundColor = [UIColor clearColor];
        self.offLight.on = NO;
        [self addSubview:self.offLight];

        self.on = NO;
    }
    return self;
}

当我运行显示此自定义 UIView 的代码时,没有任何显示。但是当我添加一个drawRect方法时......

    - (void)drawRect:(CGRect)rect
    {
        [self.onLight drawRect:rect];
        [self.offLight drawRect:rect];
    }

...子视图显示。 (显然,这不是这样做的正确方法,不仅因为它与文档所说的相反,而且因为它总是显示两个子视图,完全忽略了我的 UIView 中设置隐藏属性的其他代码视图之一,它忽略 z 排序等)

无论如何,主要问题是:当我不覆盖 drawRect: 时,为什么我的子视图不显示?

谢谢!

更新:

为了确保问题不在我的自定义子视图中,我还添加了 UILabel。所以代码如下:

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        // Consists of both an "on" light and an "off" light. We flick between the two depending upon our state.
        self.onLight = [[[LoyaltyCardNumberView alloc] initWithFrame:frame] autorelease];
        self.onLight.backgroundColor = [UIColor clearColor];
        self.onLight.on = YES;
        [self addSubview:self.onLight];

        self.offLight = [[[LoyaltyCardNumberView alloc] initWithFrame:frame] autorelease];
        self.offLight.backgroundColor = [UIColor clearColor];
        self.offLight.on = NO;
        [self addSubview:self.offLight];

        self.on = NO;

        UILabel* xLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
        xLabel.text = @"X";
        [self addSubview:xLabel];
    }
    return self;

“X”也不显示。

更新 2:

这是调用我的自定义 UIView (OffOnLightView) 的代码:

            // Container for all of the OffOnLightViews...
            self.stampSuperView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
            [self.view addSubview:self.stampSuperView];

            // Draw the stamps into the 'stamp superview'.
            NSInteger numberOfCardSpaces = (awardType == None) ? 3 : 10;
            for (NSInteger i = 1; i <= numberOfCardSpaces; i++)
            {
                OffOnLightView* newNumberView = [[[OffOnLightView alloc] initWithFrame:[self frameForStampWithOrdinal:i awardType:awardType]] autorelease];
                newNumberView.on = (i <= self.place.checkInCount.intValue);
                newNumberView.number = [NSString stringWithFormat:@"%d", i];
                [self.stampSuperView addSubview:newNumberView];
            }

【问题讨论】:

  • 你能贴出如何生成/显示父视图的代码吗?
  • @rickharrison 请参阅上面的“更新 2”。谢谢。
  • 如果设置 onlight.backgroundColor = [UIColor greenColor] 会发生什么?那你看到什么了吗?

标签: iphone uiview drawrect


【解决方案1】:

您的子视图应将其框架初始化为父 uiview 的 bounds。子视图位于相对于父框架的不同坐标系中。

self.onLight = [[[LoyaltyCardNumberView alloc] initWithFrame:self.bounds] autorelease];

【讨论】:

  • 我在 Popovers 上犯过几次同样的错误。
【解决方案2】:

您不应该手动拨打-drawRect:。如果您需要强制重绘,请致电-setNeedsDisplay

我将首先在您添加的两个子视图的-drawRect: 方法中调试(断点或NSLog()),以确保它们实际执行绘图。

还要注意如何将两个子视图设置为包含视图的完整大小(框架),并将它们的背景颜色设置为清除。我猜这是故意的,但它们可能正在显示,但由于它们具有透明背景,您看不到任何东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-26
    • 2014-01-30
    • 2015-08-29
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多