scrollViewDidEndDecelerating: BUG when changing targetContentOffset in scrollViewWillEndDragging:

Hi,

I'm changing the value of targetContentOffset in scrollViewWillEndDragging: and usually scrollViewDidEndDecelerating has the same offset I just wrote. Because scrollViewDidEndDecelerating is called right after scrollViewWillEndDragging.

But it randomly stops in another value.

Here's the log:
2020-11-19 21:53:31.312911-0300 NEW ROW: 6

2020-11-19 21:53:31.312948-0300 NEW OFFSET: 3708.000000

2020-11-19 21:53:31.312974-0300 WillEndDragging 2: 3708.000000

2020-11-19 21:53:31.625226-0300 DidEndDecelerating 1: 3708.000000

2020-11-19 21:53:31.625323-0300 DidEndDecelerating 2: 3708.000000

2020-11-19 21:53:32.378710-0300 WillEndDragging 1: 3090.000000

2020-11-19 21:53:32.378811-0300 NEW ROW: 7

2020-11-19 21:53:32.378851-0300 NEW OFFSET: 4326.000000

2020-11-19 21:53:32.378876-0300 WillEndDragging 2: 4326.000000

2020-11-19 21:53:32.775581-0300 DidEndDecelerating 1: 2472.000000

2020-11-19 21:53:32.775728-0300 DidEndDecelerating 2: 2472.000000

On row 6 everything is fine, on row 7 it breaks.

Help, apple engineers.

THE CODE:
  • (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    NSLog(@"DidEndDecelerating 1: %f", scrollView.contentOffset.y);

    if ([scrollView isKindOfClass:[UITableView class]]) {

        UITableView *tableView = (UITableView *)scrollView;

        if (tableView == self->tableView) {

            NSArray<ExperienceListTableViewCell *> *visibleCells = [self getVisibleFeedCells];

            for (ExperienceListTableViewCell *visibleCell in visibleCells) {

        //        NSLog(@"END DECELERATING: ExperienceIDBeingPlayed changing to: %@", visibleCell.experience.objectID);

                experienceIDBeingPlayed = visibleCell.experience.objectID;

                [visibleCell playVideo];

            }

        }

    }

    NSLog(@"DidEndDecelerating 2: %f", scrollView.contentOffset.y);

}


  • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView

                     withVelocity:(CGPoint)velocity

              targetContentOffset:(inout CGPoint *)targetContentOffset {

    NSLog(@"WillEndDragging 1: %f", targetContentOffset->y);

    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 handleIntentionalScrollForTableView:tableView

                                                    indexPath:indexPathWhenLiftingFinger

                                                 withVelocity:velocity

                                          targetContentOffset:targetContentOffset];

                } else {

                    [self handleUnintentionalScrollForTableView:tableView

                                                      indexPath:indexPathWhenLiftingFinger

                                                   withVelocity:velocity

                                            targetContentOffset:targetContentOffset];

                }

            } else {

                NSLog(@"no indexpath detected");

            }

        }

    }

    NSLog(@"WillEndDragging 2: %f", targetContentOffset->y);

}


  • (void)handleIntentionalScrollForTableView:(UITableView *)tableView

                                  indexPath:(NSIndexPath *)indexPathWhenLiftingFinger

                               withVelocity:(CGPoint)velocity

                        targetContentOffset:(inout CGPoint *)targetContentOffset {

    currentRow = velocity.y > 0 ? currentRow + 1 : currentRow - 1;

    NSLog(@"NEW ROW: %d", currentRow);

//    NSLog(@"TABLE HEIGHT: %f", tableView.bounds.size.height);

    targetContentOffset->y = ((CGFloat)currentRow)*tableView.bounds.size.height;

    NSLog(@"NEW OFFSET: %f", targetContentOffset->y);

//    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 = CGPointMake(0, newIndexPath.row*tableView.bounds.size.height);

//            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));

//    }

}


  • (void)handleUnintentionalScrollForTableView:(UITableView *)tableView

                                    indexPath:(NSIndexPath *)indexPathWhenLiftingFinger

                                 withVelocity:(CGPoint)velocity

                          targetContentOffset:(inout CGPoint *)targetContentOffset {

    CGFloat tableViewHeight = tableView.frame.size.height;

    CGFloat cellOffset = [SwiftCGFloat moduloBetweenWithX:targetContentOffset->y andY:tableViewHeight];

    NSInteger numberToAdd = cellOffset < (tableViewHeight/2) ? 0 : 1;

    NSIndexPath *finalIndexPath = [NSIndexPath indexPathForRow:indexPathWhenLiftingFinger.row+numberToAdd

                                                     inSection:indexPathWhenLiftingFinger.section];

    *targetContentOffset = [tableView rectForRowAtIndexPath:finalIndexPath].origin;

    NSLog(@"UNINTENTIONAL SCROLL, tableOffset: %@", NSStringFromCGPoint(*targetContentOffset));

}
scrollViewDidEndDecelerating: BUG when changing targetContentOffset in scrollViewWillEndDragging:
 
 
Q