Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate at what row will UITableView stop scrolling?

When a table has many rows, the user can flick up/down the table. This creates a scrolling animation which seems to have a deterministic length depending on the speed/length of the flick gesture. Is it possible to reliably calculate what rows in the table will be visible once the scrolling stops if there is no further user interaction?

like image 595
Grzegorz Adam Hankiewicz Avatar asked May 24 '11 20:05

Grzegorz Adam Hankiewicz


People also ask

Is Tableview scrollable?

TableView is the UI component used to display a large amount of data in a single column of scrolling views.


2 Answers

In iOS 5.0 and later there is a new API for the UIScrollViewDelegate called scrollViewWillEndDragging:withVelocity:targetContentOffset:. With this new method the stop position of the scroll can be calculated and even modified, as explained in the Video Session 100: What's New in Cocoa Touch, around the ninth minute.

like image 69
Grzegorz Adam Hankiewicz Avatar answered Sep 17 '22 16:09

Grzegorz Adam Hankiewicz


UITableView inherits from UIScrollView and you can accomplish that by using the UIScrollViewDelegate methods and the table view indexPathsForVisibleRows property to check which cell index paths are visible at the moment the scrolling stops.

You can even save the initial position from where the deceleration started, so that you can calculate whether the scroll direction was up or down, which will then let you know if is the cell that it will stop is the first or the last of the visible ones.

int startDeceleratingPosition;

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

    startDeceleratingPosition = scrollView.contentOffset.y;

}

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

    BOOL isPositionUp = startDeceleratingPosition < scrollView.contentOffset.y;     

    NSArray *paths = [_myTableview indexPathsForVisibleRows];
    UITableViewCell *cell;
    if(isPositionUp){
        cell = [_myTableview cellForRowAtIndexPath:[paths objectAtIndex:0]];
    } else {
        cell = [_myTableview cellForRowAtIndexPath:[paths lastObject]];
    }

}

An important note about the code above is that it points to the table view as a variable _myTableview instead of just casting the delegate method variable scrollView to a UITableView *, although that is just implementation details and should not affect the logic here.

like image 30
Felipe Sabino Avatar answered Sep 20 '22 16:09

Felipe Sabino