Skip to content

UITableViewをスクロールしたときに、一番下のセルがすべて出るよう吸着自動スクロールさせる方法

2011年8月18日

テーブルの一番下のセルが中途半端に隠れているときに、にゅっと動いて全部表示させてくれるためには、以下のようにTableViewに記述します。

- (void)scrollToVisibleEnd{
    NSArray *visibleArray = [[NSArray alloc] initWithArray:[self.tableView indexPathsForVisibleRows]];
    NSIndexPath *visibleTopIndexPath = [[[NSIndexPath alloc] init] autorelease];
    visibleTopIndexPath = [visibleArray objectAtIndex:0];
    int i = visibleTopIndexPath.row;
    i = i + [visibleArray count] -1;

    [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    [self scrollToVisibleEnd];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self scrollToVisibleEnd];
}

解説すると、テーブルのドラッグ、またはスクロールアニメーションが終了したときに、現在のVisibleなテーブルのセルを取り出し、その一番上からVisibleなセルの数引く1の値を出す。これをすることで、今一番下のセルの番号が得られます。

そうしてそれを、scrollToRowAtIndexPathに渡せばOK

応用すれば一番上だったり、一番下だったりをにゅっと出せるはず。
あと今思ったけど、一番下のセル番号を取り出すなら、わざわざカウントたさなくても、最初っからobjectAtIndexで指定しちゃえばいいかな。

そしていかが改良版。
上にスクロールすれば上へ、下へ移動すればしたへにゅっと自動移動します。

9/1にscrollViewDidEndDraggingにif文を追加。少し速度が早くなった。

- (void)scrollToVisibleEnd{
    NSLog(@"scrollToVisibleEnd");
    NSArray *visibleArray = [[NSArray alloc] initWithArray:[self.tableView indexPathsForVisibleRows]];
    NSIndexPath *visibleTopIndexPath = [[[NSIndexPath alloc] init] autorelease];
    visibleTopIndexPath = [visibleArray objectAtIndex:0];
    int i = visibleTopIndexPath.row;

    if (!scrollUpFlag_ && i == 0 && minus_overFlag_) {
        NSLog(@"上移動かつバウンドして一番上");
    }

    else if(scrollUpFlag_ && i + [visibleArray count] == [dataSource_ count] && plus_overFlag_){
        NSLog(@"下移動かつバウンドして一番下");
    }

    else if(scrollUpFlag_) {
        NSLog(@"うえに");
        i = i + [visibleArray count] -2;

        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }

    else if (!scrollUpFlag_){
        NSLog(@"したに");
        i = i + [visibleArray count]-1;
        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    CGRect r = self.tableView.bounds;
    float originY = r.origin.y;
    float contentSize = self.tableView.contentSize.height;
    float boundsHeight = self.tableView.bounds.size.height;

    //上下移動フラグ
    if (originY < scrollHeight_) {
        scrollUpFlag_ = YES;
    }else if (originY > scrollHeight_){
        scrollUpFlag_ = NO;
    }else if(originY == scrollHeight_){
    }

    //マイナスオーバーフラグ
    if (originY <= 0) {
        minus_overFlag_ = YES;
    }else{
        minus_overFlag_ = NO;
    }

    //プラスオーバーフラグ
    if (originY + boundsHeight >= contentSize) {
        plus_overFlag_ = YES;
    }else{
        plus_overFlag_ = NO;
    }

    scrollHeight_ = originY;

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    NSLog(@"scrollViewDidEndDragging [%d]",decelerate);
    if (!decelerate) {
        [self scrollToVisibleEnd];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    NSLog(@"scrollViewDidEndDragging");
    [self scrollToVisibleEnd];
}
広告

From → iPhone開発

コメントする

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。