UITableViewをツリー上に表示する。第2回目(テーブルのUI部品を作成)

ツリーテーブルの2回目。今回から表示部分を実装していきます。
ツリーテーブルの表示としては、大きく3つ。

  • 一番上のヘッダー
  • ツリーの親
  • ツリーの子

となります。
それぞれを、UITableの

  • ページヘッダー
  • セクションヘッダー
  • セル

で実現します。


それではUIの部分を作成していきます。
まずは、ページヘッダー。ベースとなるUIViewと上に表示するタイトルのUILabelで構成します。

@interface PageHeader : UIView {
@private
    UILabel* titleLabel_;
}
@property(strong, nonatomic, setter=setTitleName:) NSString* titleName;

@end

@implementation PageHeader

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        float fontSize = 14.0;
        float marginSize = 10.0;
        titleLabel_ = [[UILabel alloc] initWithFrame:
                       CGRectMake(marginSize,
                                  (frame.size.height - fontSize) / 2,
                                  frame.size.width - marginSize,
                                  fontSize)];
        titleLabel_.font = [UIFont fontWithName:@"Verdana" size:fontSize];
        titleLabel_.textColor = [UIColor whiteColor];
        titleLabel_.backgroundColor = [UIColor colorWithRed:0.0
                                                      green:0.0
                                                       blue:0.0
                                                      alpha:0.0];
        [self addSubview:titleLabel_];
        
        // ページヘッダーの背景色
        self.backgroundColor = [UIColor darkGrayColor];
    }
    return self;
}

- (void)setTitleName:(NSString*)titleName {
	titleLabel_.text = titleName;
}

@end



次はセクションヘッダーです。ページヘッダーと同様にUIViewをベースにします。上にツリーの開閉を視覚的に表すUIImageView(+ 開閉のイメージを保持するUIImage)、名前を表示するUILabelで構成します。


#import <UIKit/UIKit.h>

@interface SectionHeader : UIView {
@private
    UILabel* sectionNameLabel_;
    UIImageView* switchIcon_;
    int sectionNo_;
    UIImage* openImage_;
    UIImage* closeImage_;
}
@property(nonatomic) int sectionNo;
@property(strong, nonatomic, setter=setSectionName:) NSString* sectionName;
@property(nonatomic, setter=setSectionOpend:) bool sectionOpend;

@end


@implementation SectionHeader
@synthesize sectionNo = sectionNo_;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        float fontSize = 12.0;
        float marginSize = 5.0;
        float iconSize = 10.0;
        float sectionNamePos = marginSize * 2 + iconSize;
        
        // 開閉のアイコン
        switchIcon_ = [[UIImageView alloc] initWithFrame:
                             CGRectMake(marginSize,
                                        (frame.size.height - iconSize) / 2,
                                        iconSize,
                                        iconSize)];
        [self addSubview:switchIcon_];
        
        // 開閉のイメージ
        openImage_ = [UIImage imageNamed:@"open.png"];
        closeImage_ = [UIImage imageNamed:@"close.png"];
        
        // セクションの名前
        sectionNameLabel_ = [[UILabel alloc] initWithFrame:
                       CGRectMake(sectionNamePos,
                                  (frame.size.height - fontSize) / 2,
                                  frame.size.width - sectionNamePos,
                                  fontSize)];
        sectionNameLabel_.font = [UIFont fontWithName:@"Verdana" size:fontSize];
        sectionNameLabel_.textColor = [UIColor whiteColor];
        sectionNameLabel_.backgroundColor = [UIColor colorWithRed:0.0
                                                            green:0.0
                                                             blue:0.0
                                                            alpha:0.0];
        [self addSubview:sectionNameLabel_];

        // セルの背景色
        self.backgroundColor = [UIColor darkGrayColor];
}
    return self;
}

- (void)setSectionName:(NSString*)sectionName {
	sectionNameLabel_.text = sectionName;
}

- (void)setSectionOpend:(bool)sectionOpend {
    if (sectionOpend) {
        switchIcon_.image = openImage_;
    } else {
        switchIcon_.image = closeImage_;
    }
}

@end



最後にセルです。セルはUITableViewCellをベースに、上に名前を表示するUILabelで構成します。また選択状態を保持する、bool値をメンバ変数に加えておきます。

#import <UIKit/UIKit.h>

@interface CustomCell : UITableViewCell {
@private
    UILabel* cellNameLabel_;
    bool cellSelected_;
}
@property(strong, nonatomic, setter=setCellName:) NSString* cellName;
@property(nonatomic, setter=setCellSelected:, getter=cellSelected) bool cellSelected;

@end

@implementation CustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        float fontSize = 12.0;
        float marginSize = 20.0;
        float nameSize = 300.0;
        float cellHeight = 50.0; // セルの高さとりあえず固定
        cellNameLabel_ = [[UILabel alloc] initWithFrame:
                       CGRectMake(marginSize,
                                  (cellHeight - fontSize) / 2,
                                  nameSize,
                                  fontSize)];
        cellNameLabel_.font = [UIFont fontWithName:@"Verdana" size:fontSize];
        cellNameLabel_.backgroundColor = [UIColor colorWithRed:0.0
                                                         green:0.0
                                                          blue:0.0
                                                         alpha:0.0];
        [self addSubview:cellNameLabel_];
    }
    return self;
}

- (void)setCellName:(NSString*)cellName {
	cellNameLabel_.text = cellName;
}

- (bool)cellSelected {
    return cellSelected_;
}

- (void)setCellSelected:(bool)cellSelected {
    cellSelected_ = cellSelected;
    if (cellSelected_) {
        self.backgroundColor = [UIColor colorWithRed:0.7
                                               green:0.9
                                                blue:0.9
                                               alpha:1.0];
    } else {
        self.backgroundColor = [UIColor whiteColor];
    }
}

@end



これで目に見えるUI部分の作成は、ほぼ完了です。
次回は、これをUITableに組み込んでいきます。