views:

1193

answers:

2

I have a UITableView with pagingEnabled. Each cell takes up the viewing area of the table. Meaning, each cell is the same height and width as the table. I'm using custom cells that have a name property. I'd like to display the name of the current (viewable) cell in a label. This works fine for the first and last cells but anything inbetween isn't so easy. The problem is that cellForRowAtIndexPath is called twice for these middle cells. Here's what it looks like scrolling from the first to last cell and then back. I've listed the indexes in order as cellForRowAtIndexPath fires for that row:

Row             indexPath.row
 0                   0         //view loads and table appears
 1                  1,2        //user scrolls to second cell. cellForRowAtIndexPath fires twice.  First time indexPath.row is one and second time it is two.  This causes cell two's name to display in the label, rather than cell one.
 2                  2,3
 3                   3
 //user starts scrolling back to first cell
 2                  1,2 
 1                  1,0
 0                   0

I could set use an NSDate object to detect if I'm in a middle row. By diffing the previous time with current, I'll know. However, if the user scrolls really fast through the cells, that probably doesn't work. Is there another way to do it?

I've tried using variations of visiblecells properties but that didn't work. The UITableView will load the next cell even if it isn't visible, causing it to be part of the visible cells.

+1  A: 

Rather than focusing on when the UITableView requests a cell, you should be focusing on when it displays the cell, which is indicated by the delegate method tableView:willDisplayCell:forRowAtIndexPath.

Rob Napier
willDisplayCell yeilds the same results I posted.
4thSpace
+1  A: 

Well, on the off chance that you never figured out a solution, or for whoever comes to this question next, I'll provide you with the answer you were looking for. UITableView will provide you with the indexPaths you are looking for, and then UITableView will happily provide you with the cells that match those index paths:

UITableView *tableView = self.tableView; // Or however you get your table view
NSArray *paths = [tableView indexPathsForVisibleRows];

//  For getting the cells themselves
NSMutableSet *visibleCells = [[NSMutableSet alloc] init];

for (NSIndexPath *path in paths) {
    [visibleCells addObject:[tableView cellForRowAtIndexPath:path]];
}

// Now visibleCells contains all of the cells you care about.
Douglas Mayle