Нужно переопределить drawrect, если ваш UIView - просто контейнер? - PullRequest
2 голосов
/ 03 июня 2010

Согласно документации 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];
            }

Ответы [ 2 ]

3 голосов
/ 03 июня 2010

Ваши подпредставления должны иметь свой фрейм, инициализированный до границ родительского пользовательского интерфейса. Подвиды находятся в другой системе координат, относящейся к рамке родителя.

self.onLight = [[[LoyaltyCardNumberView alloc] initWithFrame:self.bounds] autorelease];
2 голосов
/ 03 июня 2010

Вы никогда не должны звонить -drawRect: вручную.Если вам нужно выполнить перерисовку, вызовите -setNeedsDisplay.

. Я бы начал с отладки (точка останова или NSLog()) в -drawRect: методах двух подпредставлений, которые вы добавляете, чтобы убедиться, что они на самом делевыполняя их рисование.

Также обратите внимание на то, как вы делаете оба подпредставления в полный размер (фрейм) содержащего представления и устанавливаете их цвета фона, чтобы очистить.Я предполагаю, что это сделано намеренно, но возможно, что они отображаются, но вы просто не можете ничего увидеть, потому что у них прозрачный фон.

...