前回の続き。今回はカスタムセルを用いたUITableViewの編集モードについて。実は前回のサンプルを編集モードにすると、このようにセルの中身が右にずれてくれません。

01

編集モードで右にずれるようにするには、SubviewをUITableViewCellに直接addSubviewするのではなく、UITableViewCell#contentViewにaddSubviewする必要があります。
前回のサンプルはすっきりしていて良いのですが、編集モードを考慮すると一工夫必要になります。

前回のサンプルについて説明しておくと

  • STCustomCellのレイアウトはSTCustomCell.xibで決定している
  • STCustomCell.xibにTableViewCellを配置している
  • その上にUILabel、UIImageViewといったSubviewを配置している
  • つまりUITableViewCell#contentViewに配置していない

問題なのはInterface BuilderではTableViewCellのcontentViewへの配置ができないことです。(自分が知る限り)

本サンプルではその対処について説明します。

サンプルコード: https://github.com/stack3/UITableViewSamples

Subclassing Cell 2を選択してください。編集ボタンを押すときちんと右にずれます。

02

STCustomCell2.h

ヘッダは前回のSTCustomCellと同じように、IBOutletでSubviewをプロパティ宣言しています。

@interface STCustomCell2 : UITableViewCell

@property(weak, nonatomic) IBOutlet UILabel *titleLabel;
@property(weak, nonatomic) IBOutlet UIImageView *photoImageView;

@end

STViewOnContentViewOfCustomCell2.xib

STCustomCell#contentViewのレイアウトです。前回は初期配置されているViewを削除してTableViewCellを配置していましたが、今回はそのままViewを使います。

Viewを選択しAttributes inspectorを選択します。Size、Status BarをNoneにしておきましょう。(xib上の見栄え用で必須ではないと思いますが)

09

Subviewの配置に関しては前回のSTCustomCell.xibと同じです。

03

File’s Ownerを選択し、Indentity inspectorを開いてください。

04


05

このようにCustom ClassをSTCustomCell2にしています。STCustomCell.xibの場合は、配置したTableViewCellのCustom ClassをSTCustomCellにしていました。今回のSTCustomCell2クラスはTableViewCellと直接ひもづかず、File’s Ownerとしてひもづきます。

次にSTCustomCell2のIBOutletとのひもづけです。File’s Ownerを選択しConnections inspectorを選択します。

06

このようにFile’s OwnerでIBOutletとひもづけされています。前回のSTCustomCellは、TableViewCellのConnection inspectorでひもづけてしていました。この点も異なるところです。

STCustomCell2.m

初期化メソッドinitWithStyle:reuseIdentifier:でxibをロードします。ownerにself(STCustomCell2)を指定していることに注目してください。

NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"STViewOnContentViewOfCustomCell2"
                                               owner:self
                                             options:nil];

xibに複数のViewが配置することもできるので、NSBundle#loadNibNamedは配列を返します。今回は1つしか配置していないので(ほとんどはそうですが・・・)、配列の先頭の要素を取り出します。

UIView *viewOnContentView = [views objectAtIndex:0];

UILabel,UIImageViewが配置されたView(viewOnContentView)を取り出せたので、これをcontentViewにaddSubviewします。

[self.contentView addSubview:viewOnContentView];

これでうまくいくように思うのですが、実際の表示はこうなってしまいます。

07

08

これはcontentViewのサイズにあわせて、viewOnContentViewがリサイズされないことが原因です。よってcontentViewへaddSubviewする前に以下のようにします。

viewOnContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.frame = viewOnContentView.bounds;
[self.contentView addSubview:viewOnContentView];
  • AutoresizingMaskで幅と高さがSuperview(この場合contentView)に合わせて伸縮するようにする
  • STCustomCell2#frameをviewContentofContentViewと同じサイズに設定
  • contentViewへaddSubviewする

これでうまく表示されるようになります。

他にも対処法としてSTCustomCell2#layoutSubviewsを実装する方法もありますが、その辺は実装の都合や好みにあわせましょう。

その7へ続く。