Post

Replies

Boosts

Views

Activity

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: Calculating the closes row to the original destination. Obtaining the offset for said row. Stepping over targetContentOffset with the obtained offset. 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: (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: 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.
1
0
501
Nov ’20
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)); }
0
0
572
Nov ’20