I have an odd situation with my UItableView.
我的UItableView有一个奇怪的情况。
I am loading images from the internet and presenting them in a uitableviewcell in an asynchronous manner. When I scroll down (i.e. row 1 to 6) the scroll scrolls down smoothly just as I expect it to.
我正在从互联网上加载图像,并以异步方式将它们呈现在uitableviewcell中。当我向下滚动(即第1行到第6行)时,滚动按照我的预期顺利向下滚动。
However, then I scroll up (i.g. row 6 to 1) the scroll jumps back. for example if I scroll from row 6 to row 5, it will jump back to row 6. The second time I try to scroll up it lets me go up to row 4, but then it scrolls me back to row 5 or 6 but usually just 5.
然而,然后我向上滚动(例如第6行到第1行)滚动回来。例如,如果我从第6行滚动到第5行,它将跳回到第6行。第二次我尝试向上滚动它让我上升到第4行,但然后它将我滚动回第5行或第6行但通常只有5。
What I don't understand is why this is happening in only one direction.
我不明白为什么这只发生在一个方向。
It seems to be effecting ios 8 but not ios 7.
它似乎影响ios 8但不影响ios 7。
Therefore it is an implementation difference in how ios8 and 7 handle the uitableview.
因此,ios8和7如何处理uitableview是一个实现差异。
How can I fix this?
我怎样才能解决这个问题?
Here is some code to give you some context
这里有一些代码可以为您提供一些上下文
- (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];
}
}
4
I found the answer in this post very helpful: Table View Cells jump when selected on iOS 8
我发现这篇文章中的答案非常有用:在iOS 8上选择时,Table View Cells会跳转
Try to implement the tableView:estimatedHeightForRowAtIndexPath:
in the UITableViewDelegate protocol. It works for me.
尝试在UITableViewDelegate协议中实现tableView:estimatedHeightForRowAtIndexPath:。这个对我有用。
1
Implement the self-sizing and correct view constraints in your storyboard.
在故事板中实现自我调整大小和正确的视图约束。
in your code put this together
在你的代码中把它放在一起
tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = CGFloat value (the initial value)
tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = CGFloat值(初始值)
1
This exact problem was happening to me while I was using the UITableViewAutomaticDimension
and the estimatedRowHeight
, as @nferocious76 suggested.
正如@ nferocious76建议的那样,当我使用UITableViewAutomaticDimension和estimatedRowHeight时,这个确切的问题发生在我身上。
The issue was that my estimatedRowHeight
was 400.0 while the actual row height was more like 80.0 (I copy/pasted it from another table view in my app with large cells). I never bothered to change it because I had read somewhere that the estimatedRowHeight
didn't really matter as long as it was greater than the actual row height, but apparently this is not the case.
问题是我的estimatedRowHeight是400.0,而实际的行高更像是80.0(我用我的应用程序中的另一个表格视图复制/粘贴了大单元格)。我从来不打算改变它,因为我曾经读过,只要它大于实际的行高,估计的RowHeight并不重要,但显然事实并非如此。
-1
You should calculate your row height yourself and you should remove everything about estimated row height in your code.
您应该自己计算行高,并且应该删除代码中估计行高的所有内容。