2014-09-29 12 views
21

Tôi có một tình huống kỳ lạ với UItableView của mình.ios8 UITableView scolling nhảy trở lại khi cuộn lên

Tôi đang tải hình ảnh từ internet và trình bày chúng trong uitableviewcell theo cách không đồng bộ. Khi tôi cuộn xuống (tức là hàng 1 đến 6), cuộn sẽ cuộn xuống trơn tru như tôi mong đợi.

Tuy nhiên, sau đó tôi cuộn lên (ví dụ: hàng 6 đến 1) cuộn sẽ nhảy trở lại. ví dụ nếu tôi cuộn từ hàng 6 sang hàng 5, nó sẽ nhảy trở lại hàng 6. Lần thứ hai tôi cố gắng cuộn lên cho phép tôi chuyển lên hàng 4, nhưng sau đó nó cuộn tôi về hàng 5 hoặc 6 nhưng thường chỉ 5.

Điều tôi không hiểu là tại sao điều này xảy ra chỉ theo một hướng.

Nó dường như được thực ios 8 nhưng không ios 7.

Vì vậy nó là một sự khác biệt thực hiện trong cách iOS8 và 7 xử lý các UITableView.

Làm cách nào để khắc phục sự cố này?


Dưới đây là một số mã để cung cấp cho bạn một số bối cảnh

- (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

Mã của bạn để định cấu hình các ô trông như thế nào? –

+0

Tôi phát hiện ra rằng lỗi này ảnh hưởng đến ios 8 nhưng không phải là ios 7 – DerrickHo328

+0

@ Calimari328 Vui lòng trả lời câu hỏi bạn đã được hỏi. Không có lỗi iOS 8 ở đây. Đây là một cái gì đó _you_ đang làm sai. Nếu bạn muốn được giúp đỡ, bạn phải _show_ những gì bạn đang làm. – matt

Trả lời

4

Tôi tìm thấy câu trả lời trong bài viết này rất hữu ích: Table View Cells jump when selected on iOS 8

Cố gắng thực hiện tableView:estimatedHeightForRowAtIndexPath: trong giao thức UITableViewDelegate. Nó làm việc cho tôi.

+3

Tôi thực sự có phương thức ủy nhiệm được triển khai với một giá trị được mã hóa cứng. Nó vẫn nhảy xung quanh. Nhưng có thể lỗi liên quan đến chiều cao bị ghi đè. Tôi sẽ khám phá những gì sẽ xảy ra khi tôi điều chỉnh tất cả các phương pháp khác liên quan đến chiều cao – DerrickHo328

+0

Cảm ơn !! Nó cũng có tác dụng với tôi. –

1

Thực hiện các hạn chế chế độ xem tự định kích thước và chính xác trong bảng phân cảnh của bạn.

trong mã của bạn đặt này cùng

tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = CGFloat value (giá trị ban đầu)

-1

Bạn nên tự mình tính chiều cao hàng và bạn nên xóa mọi thứ về chiều cao hàng ước tính trong mã của mình.

1

vấn đề chính xác này đã xảy ra với tôi trong khi tôi đang sử dụng UITableViewAutomaticDimensionestimatedRowHeight, như @ nferocious76 gợi ý.

Vấn đề là estimatedRowHeight của tôi là 400.0 trong khi chiều cao hàng thực tế lớn hơn 80,0 (tôi sao chép/dán nó từ chế độ xem bảng khác trong ứng dụng của tôi với các ô lớn). Tôi không bao giờ bận tâm để thay đổi nó bởi vì tôi đã đọc ở đâu đó rằng estimatedRowHeight không thực sự quan trọng miễn là nó là lớn hơn so với chiều cao hàng thực tế, nhưng rõ ràng đây không phải là trường hợp.

Các vấn đề liên quan