アーカイブ

Archive for 2009年10月

UITableViewCellのサブビューをハイライトさせる

UITableViewをタップすると、行がハイライト表示されます。背景は青く、文字は白く。
これはタップを検出したときに、UITableViewCellのsetHighlighted:animated:が呼び出された時の応答です。
ここに、若干の謎があります。

通常UITableViewCellはサブビューとして、UIImageViewやUILabelを持っています。この二つのクラスは、setHighlighted:というメソッドを持っているので、それが呼び出されているのでしょう。
しかし、UIViewならどんなクラスであってもサブビューとして追加できる事を考えると、これは妙です。
サブビューのクラスが上記二種類かどうか判定しているような、残念な実装かもしれせん。
少なくても、UIHighlightableなどというプロトコルも、見当たりません。
これは、独自のUIViewのサブクラスを用意した場合に、ハイライトに応答する方法が無いという事です。

解決方法
力技的には、UITableViewCellのsetHighlighted:animated:をオーバーライドしてしまう事を考えると思いますが、もっと良い方法が見つかりました。
実はUITableViewCellはサブビューをハイライトしようとした時は、該当するUIViewがsetHighlighted:を実装しているかどうか調べます。
実装していれば呼び出すという事です。
つまり、プロトコルのオプショナルメソッドや、非形式プロトコルと同様な扱いになっています。
以下は「MyView」と文字を表示するだけのUIViewのサブクラスですが、UITableViewCellに追加するとちゃんとハイライトします。

@interface MyView : UIView {
    BOOL highlighted;
}

@property (nonatomic, getter=isHighlighted) BOOL highlighted;

@end

@implementation MyView

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
         self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    if (highlighted) {
        [[UIColor whiteColor] set];
    }
    else {
        [[UIColor blackColor] set];
    }
    [@"MyView" drawInRect:self.bounds withFont:[UIFont systemFontOfSize:[UIFont systemFontSize]]];
}

@synthesize highlighted;

- (void)setHighlighted:(BOOL)aHighlighted {
    if (highlighted != aHighlighted) {
        highlighted = aHighlighted;
        [self setNeedsDisplay];
    }
}

@end
広告
カテゴリー:開発 タグ: ,