2014-09-29 107 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並不重要,只要它是大於比實際的行高,但顯然情況並非如此。