rectForRowAtIndexPath returns a mistaken value

Hello,

I'm using scrollViewWillEndDragging:withVelocity:targetContentOffset: to mimic a UITableView that, when scrolled, ends on one entire cell and shows none of it's neighbours.

The cell's size is equal to the UITableView bounds, so you can imagine the effect.

I achieve this by:
  1. Calculating the closes row to the original destination.

  2. Obtaining the offset for said row.

  3. Stepping over targetContentOffset with the obtained offset.

  4. Fixing the targetContentOffset value if it's mistaken

The PROBLEM is in step 2, rectForRowAtIndexPath is (randomly) returning a mistaken value. That's why step 4 is needed, to fix the rectForRowAtIndexPath mistake.

Here's the code:
Code Block
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset {
    if ([scrollView isKindOfClass:[UITableView class]]) {
        UITableView *tableView = (UITableView *)scrollView;
        if (tableView == self->tableView) {
            NSIndexPath *indexPathWhenLiftingFinger = [tableView indexPathForRowAtPoint:*targetContentOffset];
            if (indexPathWhenLiftingFinger != nil) {
                if (velocity.y != 0) {
                    [self handleIntentionalScroll:indexPathWhenLiftingFinger
                                     withVelocity:velocity
                              targetContentOffset:targetContentOffset];
                } else {
                    [self handleUnintentionalScrollForTableView:tableView
                                                      indexPath:indexPathWhenLiftingFinger
                                                   withVelocity:velocity
                                            targetContentOffset:targetContentOffset];
                }
            } else {
                NSLog(@"no indexpath detected");
            }
        }
    }
}
- (void)handleIntentionalScroll:(NSIndexPath *)indexPathWhenLiftingFinger
                   withVelocity:(CGPoint)velocity
            targetContentOffset:(inout CGPoint *)targetContentOffset {
    if (velocity.y > 0) {
        NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:indexPathWhenLiftingFinger.row+1 inSection:indexPathWhenLiftingFinger.section];
        NSLog(@"newRow: %ld", (long)newIndexPath.row);
        if (newIndexPath.row < [tableView numberOfRowsInSection:newIndexPath.section]) {
            *targetContentOffset = [tableView rectForRowAtIndexPath:newIndexPath].origin;
            if (targetContentOffset->y == newIndexPath.row*tableView.bounds.size.height) {
                NSLog(@"CORRECT offset: %f", targetContentOffset->y);
            } else {
                NSLog(@"INCORRECT offset: %f", targetContentOffset->y);
                targetContentOffset->y = newIndexPath.row*tableView.bounds.size.height;
                NSLog(@"corrected to: %f", targetContentOffset->y);
            }
        } else {
            NSLog(@"newrow is the last row in the section");
        }
    } else {
        NSLog(@"velocity <= 0, no need for new row");
        *targetContentOffset = [tableView rectForRowAtIndexPath:indexPathWhenLiftingFinger].origin;
        NSLog(@"tableOffset: %@", NSStringFromCGPoint(*targetContentOffset));
    }
}


And the log:
Code Block
newRow: 1
CORRECT offset: 618.000000
table stopped moving at: 618.000000
newRow: 2
CORRECT offset: 1236.000000
newRow: 4
CORRECT offset: 2472.000000
newRow: 5
CORRECT offset: 3090.000000
newRow: 6
CORRECT offset: 3708.000000
newRow: 7
CORRECT offset: 4326.000000
newRow: 8
CORRECT offset: 4944.000000
newRow: 9
CORRECT offset: 5562.000000
newRow: 11
INCORRECT offset: 6520.000000
corrected to: 6798.000000


QUESTION: Is there a better way to obtain the rect for a row?

Please, I've been struggling with this for weeks now.

PROBLEM is in step 2, rectForRowAtIndexPath is (randomly) returning a mistaken value. That's why step 4 is needed

What are those steps in your code ?

Note: when you post code, use Paste and Match Style to avoid all the extra blank lines that make code harder to understand.
rectForRowAtIndexPath returns a mistaken value
 
 
Q