スプーキーズの中の人。

スプーキーズの中の人が徒然なるままに、垂れ流します。

セルを下から上に表示するUITableView

こんにちは。 開発の中山です。

UITableViewと言えばiOSにおけるUIの要ですが、このUITableViewで、セルを下から上に並べて表示する方法についてご紹介します。

そもそも下から上にセルを並べるというUIが一般的ではないということもあり、あいにくUITableViewにはそのようなAPIは用意されていません。かと言って自前で一から実装し直すのは、セルを再利用する仕組みなども考えると中々骨が折れそうです。

そこで今回は、UIViewのtransformプロパティというものを使います。これを使うと一見強引なビューの変形をすることができます。

では、実際にやってみましょう。 まず標準のテーブルビューです。

このテーブルビューのtransformプロパティに、180°回転させるCGAffineTransformをセットします。

[objc highlight="3"] - (void)viewDidLoad { [super viewDidLoad]; _tableView.transform = CGAffineTransformMakeRotation(M_PI); } [/objc]

180°回転しましたが、セルの内容まで一緒に回転してしまっています。そこで、今度はセルを逆方向に回転させることでテーブルビューの回転を相殺させてみます。

[objc highlight="4"] - (UITableViewCell)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath)indexPath { static NSString cellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; cell.transform = CGAffineTransformMakeRotation(-M_PI); cell.textLabel.text = [NSString stringWithFormat:@"Cell %d", indexPath.row]; return cell; } [/objc]

見事に下から上にセルが並んでいます!と思いきや、実際に触ってスクロールしてみると、こんな風にスクロールバーが画面左側に表示されてしまいます。

そこで、今度はUIScrollViewのプロパティ、scrollIndicatorInsetsを変更してみます。scrollIndicatorInsetsは、スクロールバーをビューの端からどれだけ内側に表示するかというプロパティです。この場合、画面左側からビューの幅分だけググっと右側に押し込むとうまくいきそうです。ただし、テーブルビューは180°回転している状態なので、画面左から押し込むために変更する値はscrollIndicatorInsets.rightになることに注意して下さい。

[objc highlight="6,7,8,9,10,11,12,13"] - (void)viewDidLoad { [super viewDidLoad];

_tableView.transform = CGAffineTransformMakeRotation(M_PI);

static CGFloat innerOffset = 9.0;
UIEdgeInsets insets = UIEdgeInsetsMake(
    0.0, // top
    0.0, // left
    0.0, // bottom
    CGRectGetWidth(_tableView.frame) - innerOffset // right
);
_tableView.scrollIndicatorInsets = insets;

} [/objc]

うまくいきました。完成です。

ただ、tableHeaderViewは逆回転をしても画面下に表示されてしまったり、セクションヘッダのビューは逆回転できなかったりと、完全ではありません。完全な実装をするには一から再発明する必要がありそうです。

今回の方法を使った、透過的に使えるUITableViewとUITableViewCellのサブクラスのサンプルです。 ReversedTableViewSample