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

July 9, 2011

iPhone, iPad で長いリストを扱うときにセクションの固まり項目をきれいに表示させたくなります。
Newstrush というニュースリーダーアプリでは、記事のカテゴリ毎にセクション化しています。
f:id:tilfin:20110709231244p:image
↓ このアプリではセクションのヘッダ部分をタップすると、そこが先頭にくるように細工をしてあります。
f:id:tilfin:20110709231245p:image
実装方法は下記の通り。

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

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

TableSectionHeaderView.h
1
2
3
4
5
6
7
8
#import <UIKit/UIKit.h>
@interface TableSectionHeaderView : UIView {
@private
id _tableView;
int _sectionIndex;
}
\- (id)initWithSectionIndex:(NSUInteger)index forTable:(id)tableView;
@end
TableSectionHeaderView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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 メソッドをオーバーライドで実装します。

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

tilfin freelance software engineer