Подтвердить что ты не робот

IOS8 UITableView scolling возвращается при прокрутке вверх

У меня странная ситуация с моим UItableView.

Я загружаю изображения из Интернета и представляю их в uitableviewcell асинхронно. Когда я прокручиваю вниз (т.е. Строка с 1 по 6), свиток прокручивается плавно, как я ожидаю.

Однако, тогда я прокручиваю вверх (например, строка 6 на 1), прокрутка отскакивает назад. например, если я перейду от строки 6 к строке 5, он вернется к строке 6. Во второй раз, когда я пытаюсь прокрутить вверх, он позволяет мне перейти к строке 4, но затем он прокручивает меня до строки 5 или 6, но обычно всего 5.

Я не понимаю, почему это происходит только в одном направлении.

Кажется, что это работает с ios 8, но не с ios 7.

Следовательно, это разница в реализации в том, как ios8 и 7 обрабатывают uitableview.

Как я могу это исправить?


Вот некоторый код, который даст вам некоторый контекст

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    CVFullImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    CVComicRecord *comicRecord = self.comicRecords[indexPath.row];
    [cell.loaderGear stopAnimating];
    [cell.text setText:comicRecord.title];
    NSString *UUID = comicRecord.fullImagePageURL.absoluteString;
    [cell setUUID:UUID];
    //Check if image is in the cache
    UIImage *fullImage = [self.contentViewCache objectForKey:UUID];
    [cell setComicFullImage:fullImage];

    if (fullImage) {
        return cell;
    }

    [cell.loaderGear startAnimating];

    [self requestImageForIndexPath:indexPath];
    return cell;
}

- (void)requestImageForIndexPath:(NSIndexPath *)indexPath {
    CVComicRecord *comicRecord = self.comicRecords[indexPath.row];
    NSString *UUID = comicRecord.fullImagePageURL.absoluteString;

    if ([self.contentViewCache objectForKey:UUID]) {
        //if it is already cached, I do not need to make a request.
        return;
    }

    id fd = CVPendingOperations.sharedInstance.fullDownloadersInProgress[UUID];

    if (fd) {
        //if it is in the queue you do no need to make a request
        return;
    }

    comicRecord.failedFull = NO;
    CVFullImageDownloader *downloader = [[CVFullImageDownloader alloc] initWithComicRecord:comicRecord withUUID:UUID];
    [CVPendingOperations.sharedInstance.fullDownloaderOperationQueue addOperation:downloader];
    //when operation completes it will post a notification that will trigger an observer to call fullImageDidFinishDownloading
}

- (void)fullImageDidFinishDownloading:(NSNotification *)notification {
    CVComicRecord *comicRecord = notification.userInfo[@"comicRecord"];
    NSString *UUID = notification.userInfo[@"UUID"];
    UIImage *fullImage = notification.userInfo[@"fullImage"];

    comicRecord.failedFull = NO;

    [self.contentViewCache setObject:fullImage forKey:UUID];
    dispatch_async(dispatch_get_main_queue(), ^{
        for (NSIndexPath *indexPath in [self.tableView indexPathsForVisibleRows]) {
            CVFullImageTableViewCell *cell = (id)[self.tableView cellForRowAtIndexPath:indexPath];
            if (cell) {
                if ([cell.UUID isEqualToString:UUID]) {
                    [cell.loaderGear stopAnimating];
                    [cell setComicFullImage:fullImage];
                    [cell layoutIfNeeded];
                }
            }
        }
    });
}

#pragma mark - Scroll

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    static int oldOffset = 0;
    int newOffset = scrollView.contentOffset.y;

    int dy = newOffset- oldOffset;
    if (dy > 0) {
        [self hideNavigationbar:YES animationDuration:0.5];
    } else  if (dy < 0) {
        [self hideNavigationbar:NO animationDuration:0.5];
    }

    oldOffset = newOffset;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (decelerate == NO) {
        [self prioritizeVisisbleCells];
        //currentPage is a property that stores that last row that the user has seen
        [self setCurrentPage:[self currentlyViewedComicIndexPath].row];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self prioritizeVisisbleCells];
    //currentPage is a property that stores that last row that the user has seen
    [self setCurrentPage:[self currentlyViewedComicIndexPath].row];
}

- (void)prioritizeVisisbleCells {
    NSArray *ips = [self.tableView indexPathsForVisibleRows];
    NSArray *activeIndexPaths = [CVPendingOperations.sharedInstance.fullDownloadersInProgress allKeys];

    //add visible cells to queue first
    NSSet *visible = [NSSet setWithArray:ips];
    NSMutableSet *invisible = [NSMutableSet setWithArray:activeIndexPaths];
    [invisible minusSet:visible];

    for (NSIndexPath *ip in invisible) {
        NSOperation *op = CVPendingOperations.sharedInstance.fullDownloadersInProgress[ip];
        [op setQueuePriority:NSOperationQueuePriorityNormal];
    }

    for (NSIndexPath *ip in visible) {
        NSOperation *op = CVPendingOperations.sharedInstance.fullDownloadersInProgress[ip];
        [op setQueuePriority:NSOperationQueuePriorityHigh];
    }
}
4b9b3361

Ответ 2

Внедрите самостоятельные размеры и правильные ограничения вида в своем раскадровке.

в коде добавьте это вместе

tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = Значение CGFloat (начальное значение)

Ответ 3

Эта точная проблема происходила со мной, когда я использовал UITableViewAutomaticDimension и estimatedRowHeight, как предположил @nferocious76.

Проблема заключалась в том, что мой estimatedRowHeight был 400.0, в то время как фактическая высота строки больше напоминала 80.0 (я копировал/вставлял ее из другого вида таблицы в моем приложении с большими ячейками). Я никогда не потрудился изменить его, потому что я где-то читал, что estimatedRowHeight не имеет значения, если он больше, чем фактическая высота строки, но, по-видимому, это не так.

Ответ 4

Вы должны сами рассчитать высоту своей строки, и вы должны удалить все, что связано с оценкой высоты строки в вашем коде.