I have a need to make a UITableView only display whole cells at the top of the cell, so when the table is moved or scrolled it should animate to make a whole cell visible at the top of the table if it has happened to stop with a cell partially off the top. This can be easily done using visibleCells and scrollToRowAtIndexPath methods of UITableView, BUT the cell should not always scroll down to move the partial cell into view - if the cell at top is more than 50% gone it should go completely with the next cell (i.e. index 1 in the array returned by visibleCells) moving to the top of the table.
I've tried a few things to make this happen but I don't think I am understanding the way frame and bounds work between a UITableView and its UITableViewCells. Any help?
UPDATE - any comments on the following solution? Point out problems for the credit.
// cast to UITableView* here is because the inherited delegate methods for
// UIScrollView, scrollViewDidEndDragging and scrollViewDidEndDecelerating
// are where this process begins
NSArray* visiblePaths = [(UITableView*)scrollView indexPathsForVisibleRows];
NSIndexPath* topCellIndex;
CGRect tableFrame = myTableView.frame;
UITableViewCell* firstVisibleCell = [[myTableView visibleCells] objectAtIndex:0];
CGPoint convPoint = [myTableView convertPoint:firstCell.frame.origin
toView:firstCell.superview.superview];
// point of interest is one half cell's height
// from the top of the table. Either a cell at the top of the table
// occupies this space (is more than halfway visible) or the second
// cell (the first cell is less than halfway visible) is there.
// convPoint is the origin of the cell in the same coordinate system
// as myTableView's origin. When it is more than half of a cell height
// above tableView origin the next cell should take top position.
if(convPoint.y + (firstVisibleCell.frame.size.height / 2) < tableFrame.origin.y) {
topCellIndex = [visiblePaths objectAtIndex:1];
} else {
topCellIndex = [visiblePaths objectAtIndex:0];
}
// return a 1-based index indicating which of the visible cells
// should be moved to the top of the table
return (topCellIndex.row + 1);