読者です 読者をやめる 読者になる 読者になる

UITableViewでセクションヘッダをタップするとそのセクションの先頭にスクロールさせるには

iPhone, iPad で長いリストを扱うときにセクションの固まり項目をきれいに表示させたくなります。
Newstrush というニュースリーダーアプリでは、記事のカテゴリ毎にセクション化しています。

このアプリではセクションのヘッダ部分をタップすると、そこが先頭にくるように細工をしてあります。

実装方法は下記の通り。

セクションヘッダビューの定義

セクションヘッダ用のカスタムViewを作成します。
カスタム init メソッドでセクションインデックスとテーブルビューのポインタを渡して、touchesEnded イベントでUITableViewの scrollRectToVisible メソッドにセクションから始まる画面領域の矩形を渡して呼び出します。

TableSectionHeaderView.h
#import <UIKit/UIKit.h>

@interface TableSectionHeaderView : UIView {

@private
    id _tableView;
    int _sectionIndex;
}

- (id)initWithSectionIndex:(NSUInteger)index forTable:(id)tableView;

@end
TableSectionHeaderView.m
#import "TableSectionHeaderView.h"

@implementation TableSectionHeaderView

- (id)initWithSectionIndex:(NSUInteger)index forTable:(id)tableView {
    self = [super init];
    if (self) {
        _sectionIndex = index;
        _tableView = tableView;
    }
    return self;
}

- (void)dealloc {
    _tableView = nil;
    [super dealloc];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    CGRect rect_ = [_tableView rectForSection:_sectionIndex];
    rect_.size.height = [_tableView frame].size.height;
    [_tableView scrollRectToVisible:rect_ animated:YES];
}

@end

※ UITableView の参照は相互で retain しないように id にしてあります。

UITableViewController

TableSectionHeaderViewの生成部分を UITableViewController で viewForHeaderInSection:section メソッドをオーバーライドで実装します。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
      UIView *headerView_ = [[TableSectionHeaderView alloc] initWithSectionIndex:section forTable:self.tableView];
      return [headerView_ autorelease];
}