UITableView の横スクロール方法は多くの方が語られておりますが、今回はちょっとした Tips も含めて書いてみました。
UITableView は基本的に縦スクロールしか機能がないので、その View を90度回転させてやることで横スクロールを実現させます。
その際、UITableView を直接90度回転させるのではなく、UIView の上に UITableView を載せ、その UIView を回転させるのがコツです。
そうしないと UITableView のタッチ検出がうまくいかない時があるそうです。
以下のサイトを参考にしました。
UITableViewを回転して横スクロールする際のタッチのエラーと対策方法 | Zero4Racer PRO Developer's Blog
なお今回のサンプルプロジェクトは ARC を使って実装してみました。
UIViewController と、UIView、UITableView の関係は以下の図のようになっています。
赤い矢印が strong 参照で、青い矢印が weak 参照です。
UIViewController のヘッダファイルは以下のようになります。
@interface ImageViewSampleViewController : UIViewController <UITableViewDataSource,UITableViewDelegate> @property (nonatomic,weak)IBOutlet UITableView *tableView; @property (nonatomic,weak)IBOutlet UIView *bgView; @endbgView と tableView が weak 参照なのは、ルートとなる view が bgView を保持し、bgView が tableView を保持するので、あえて UIViewController がこれらを保持する必要が無いからです。
逆に保持してしまうと、dealloc メソッドを実装して、その中で bgView、tableView を明示的に解放してやらないとメモリーリークを起こしてしまいますので注意して下さい。
上記の図を参考に、InterfaceBuilder で各ビューを配置します。
デフォルトの view の上に bgView を配置し、その上に tableView を配置します。
bgView と tableView の Outlet 接続はもちろんのこと、tableView の dataSource と delegate を File's Owner(UIViewController) に設定するのを忘れないで下さい。僕はよく忘れて、いつも途方に暮れます。(苦笑)
更に、tableView の Row Height の値を 320 にしておきます。こうすることで1画面1画像の画像ビュアーになりますが、この辺は各自のデザインしだいです。
Header、Footer のサイズは、今回は使わないのでいくつでもいいです。
さて、次はいよいよ UITableView の回転です。
UIViewController の実装ファイルの、変更点、追加点のみを以下に書き出しました。
- (void)viewDidLoad { [super viewDidLoad]; // bgView の回転 (時計回りに90°) // -90°にしないのにはわけがある! CGRect originalFrame = self.bgView.frame; self.bgView.center = CGPointMake(320/2,480/2); self.bgView.transform = CGAffineTransformMakeRotation(M_PI * 90 / 180.0f); self.bgView.frame = originalFrame; // ページ単位でスクロールをかっちり止めるにはYES self.tableView.pagingEnabled = YES; // UITableViewも親につられて時計回りに90°回転しているので、一番下のrowが左端になる。 // よって一番下のrowを最初に表示させる。 NSIndexPath* indexPath = [NSIndexPath indexPathForRow:IMAGE_MAX-1 inSection:0]; [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self.tableView reloadData]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // 画像の数を返す return IMAGE_MAX; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"ImageCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } NSString *cellImageName = [NSString stringWithFormat:@"Sample%d.png",IMAGE_MAX-indexPath.row]; cell.imageView.image = [UIImage imageNamed:cellImageName]; // UITableViewが時計回りに90°回転しているので、cell のコンテンツビューを 反時計回りに90°回転させる。 cell.contentView.transform = CGAffineTransformMakeRotation(M_PI * (-90) / 180.0f); return cell; } #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"select = %d",indexPath.row); }何も考えずに実装するなら、bgView は反時計回りに90°(-90°)回転させたほうが楽です。
そうすると UITableView の一番上のセルが左端になって、一番下のセルが右端なります。
左から右へスクロールするという iPhone の写真アプリと同じになるので都合がよいのです。
ではなぜそうしないかというと、反時計回りに90°回転させると UITableView のスクロールバーが画面の上端にきてしまうためです。
見栄え的にもウザいですし、何より UIScrollView を配置した時と、スクロールバーの位置が違うのでデザインの統一感がなくなってしまいます。
それ故、わざわざ時計回りに90°回転させています。
その結果、UITableView の一番下のセルが左端になるので、表示するセルの順番もそれに合わせてやらなければなりません。
その辺の処理は、tableView:cellForRowAtIndexPath: メソッドを見て頂けると分かると思います。
indexPath.row で得られる値を元に、表示する画像のファイル名を決めていますが
Sample1.png→Sample2.png→Sample3.png
とするところを
Sample3.png→Sample2.png→Sample1.png
となるようにしています。
0 件のコメント:
コメントを投稿