2014-09-29 56 views
21

我有一个奇怪的情况与我的UItableView。ios8 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]; 
    } 
} 
+0

你配置单元格的代码是什么样的? – 2014-09-29 18:14:50

+0

我发现这个bug影响ios 8而不是ios 7 – DerrickHo328 2014-09-29 18:25:35

+0

@ Calimari328请回答你被问到的问题。这里没有iOS 8的bug。这是_you_做错了。如果你需要帮助,你必须显示你在做什么。 – matt 2014-09-29 18:33:40

回答

4

我找到了答案在这个职位非常有帮助:Table View Cells jump when selected on iOS 8

试图实现在的UITableViewDelegate协议tableView:estimatedHeightForRowAtIndexPath:。这个对我有用。

+3

我实际上已经使用硬编码值实现了该委托方法。它仍在跳动。但也许这个错误与高度被覆盖有关。我将探索当我调整所有其他方法相关的高度 – DerrickHo328 2014-10-03 17:10:19

+0

谢谢!它也适用于我。 – 2015-08-26 11:57:18

1

在故事板中实现自定尺寸和正确的视图约束。

在你的代码

把这个一起

tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = CGFloat值(初始值)

-1

您应该自己计算行高度,并且应该删除代码中估计行高的所有内容。

1

在我使用UITableViewAutomaticDimensionestimatedRowHeight时,发生了这个确切的问题,正如@ n​​ferocious76所建议的那样。

问题是,我的estimatedRowHeight是400.0,而实际的行高更像80.0(我从我的应用程序中的大单元格中的另一个表视图复制/粘贴它)。我从来没有打算改变它,因为我曾经在某处读过estimatedRowHeight并不重要,只要它是大于比实际的行高,但显然情况并非如此。