2

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内の隠されたプロパティを設定する他のコードを完全に無視しているためです。ビューの1つで、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];
            }
4

2 に答える 2

3

サブビューでは、フレームを親uiviewの境界に初期化する必要があります。サブビューは、親のフレームを基準にした別の座標系にあります。

self.onLight = [[[LoyaltyCardNumberView alloc] initWithFrame:self.bounds] autorelease];
于 2010-06-03T02:53:52.137 に答える
2

-drawRect:手動で呼び出すことは絶対にしないでください。再描画を強制する必要がある場合は、を呼び出します-setNeedsDisplay

追加する2つのサブビューのメソッドでデバッグ(ブレークポイントまたはNSLog())を実行して、実際に描画が実行されていることを確認します。-drawRect:

また、両方のサブビューを含むビューのフルサイズ(フレーム)にし、背景色をクリアに設定する方法にも注意してください。これは意図的なものだと思いますが、表示されている可能性はありますが、背景が透明なため何も見えません。

于 2010-06-03T00:47:06.493 に答える