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:
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);
}
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);
}
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));
// }
}
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));
}
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 {
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
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
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
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));
}