gpt4 book ai didi

ios - UICollectionView indexPathsForVisibleItems 不更新新的可见单元格

转载 作者:可可西里 更新时间:2023-11-01 03:13:25 25 4
gpt4 key购买 nike

我有一个 ViewController,里面有一个 CollectionView。加载 View 时,可见单元格(9 个单元格)会正确显示。当我向下滚动时,我想通过调用 partnerCollectionView 的 indexPathsForVisibleItems 来使用 loadImagesForOnscreenRows 加载 Collection View 中的可见项。但是当 loadImagesForOnscreenRows 时,indexPathsForVisibleItems 总是包含前 9 个单元格,即使单元格 10 到 18 应该在屏幕上可见。我使用的代码是:

#import "PartnerListViewController.h"
#import "AppDelegate.h"
#import "Partner.h"
#import "ImageLoader.h"
#import "PartnerDetailViewController.h"

@interface PartnerListViewController ()

@end

@implementation PartnerListViewController

@synthesize lblTitle;
@synthesize partnerCollectionView;

@synthesize imageDownloadsInProgress;

@synthesize fetchedResultsController;
@synthesize managedObjectContext;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.

AppDelegate * appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
imageDownloadsInProgress = [NSMutableDictionary dictionary];
appDelegate = nil;

[self setupFetchedResultsController];
[partnerCollectionView reloadData];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Collection view data source

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return [[fetchedResultsController sections] count];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"PartnerCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

Partner *partner = [self.fetchedResultsController objectAtIndexPath:indexPath];

UIImageView *imageView = (UIImageView *)[cell viewWithTag:100];
if (!partner.image)
{
imageView.image = [UIImage imageNamed:@"annotationMap.png"];
if (self.partnerCollectionView.dragging == NO && self.partnerCollectionView.decelerating == NO)
{
[self startDownload:partner.imageUrl forIndexPath:indexPath];
}
} else {
imageView.image = [UIImage imageWithData:partner.image];
}

UILabel *lblTitlePartner = (UILabel *)[cell viewWithTag:101];
lblTitlePartner.text = partner.title;
lblTitlePartner.font = [UIFont fontWithName:fontName size:10];

return cell;
}

#pragma mark - Table cell image support
- (void)startDownload:(NSString *)urlString forIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"startDownload:%ld", (long)indexPath.row);

ImageLoader *imageLoader = [imageDownloadsInProgress objectForKey:indexPath];
imageLoader = [[ImageLoader alloc] init];
imageLoader.urlString = urlString;
imageLoader.indexPathTableView = indexPath;
imageLoader.delegate = (id)self;
[imageDownloadsInProgress setObject:imageLoader forKey:indexPath];
[imageLoader startDownload];
}

// this method is used in case the user scrolled into a set of cells that don't have their app icons yet
- (void)loadImagesForOnscreenRows
{
NSArray *visiblePaths = [self.partnerCollectionView indexPathsForVisibleItems];
NSMutableArray *rowsArray = [NSMutableArray arrayWithCapacity:[visiblePaths count]];
[visiblePaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) {
NSLog(@"loadImagesForOnscreenRows1%@", @(indexPath.item));
[rowsArray addObject:@(indexPath.item)];
}];
for (NSIndexPath *indexPath in visiblePaths)
{
NSLog(@"loadImagesForOnscreenRows2:%ld", (long)indexPath.row);

Partner *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

if (!item.image) // avoid the app icon download if the app already has an icon
{
[self startDownload:item.imageUrl forIndexPath:indexPath];
}
}
}

// called by our ImageDownloader when an icon is ready to be displayed
- (void)imageLoaderDidFinishDownloading:(NSIndexPath *)indexPath
{
NSLog(@"imageLoaderDidFinishDownloading:%ld", (long)indexPath.row);

ImageLoader *imageLoader = [imageDownloadsInProgress objectForKey:indexPath];
if (imageLoader != nil)
{
// Save the newly loaded image
Partner *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
item.image = UIImageJPEGRepresentation(imageLoader.image, 1.0);

[self performSelectorOnMainThread:@selector(saveItem) withObject:nil waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}
}

- (void)saveItem
{
[self.managedObjectContext save:nil];
}

- (void)reloadData
{
[self.partnerCollectionView reloadData];
}

#pragma mark deferred image loading (UIScrollViewDelegate)

// Load images for all onscreen rows when scrolling is finished
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
}
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}

- (void)setupFetchedResultsController
{
// 1 - Decide what Entity you want
NSString *entityName = @"Partner"; // Put your entity name here
NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entityName);

// 2 - Request that Entity
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

// 4 - Sort it if you want
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"title" ascending:NO selector:@selector(localizedCaseInsensitiveCompare:)]];
// 5 - Fetch it
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}

@end

这导致输出:

可见项目的初始显示

2013-09-02 06:45:21.940 [2564:c07] startDownload:0
2013-09-02 06:45:21.943 [2564:c07] imageLoaderDidFinishDownloading:0
2013-09-02 06:45:21.950 [2564:c07] startDownload:1
2013-09-02 06:45:21.951 [2564:c07] imageLoaderDidFinishDownloading:1
2013-09-02 06:45:21.958 [2564:c07] startDownload:2
2013-09-02 06:45:21.959 [2564:c07] imageLoaderDidFinishDownloading:2
2013-09-02 06:45:21.965 [2564:c07] startDownload:3
2013-09-02 06:45:22.063 [2564:c07] imageLoaderDidFinishDownloading:3
2013-09-02 06:45:22.072 [2564:c07] startDownload:4
2013-09-02 06:45:22.073 [2564:c07] imageLoaderDidFinishDownloading:4
2013-09-02 06:45:22.081 [2564:c07] startDownload:5
2013-09-02 06:45:22.082 [2564:c07] imageLoaderDidFinishDownloading:5
2013-09-02 06:45:22.089 [2564:c07] startDownload:6
2013-09-02 06:45:22.090 [2564:c07] imageLoaderDidFinishDownloading:6
2013-09-02 06:45:22.098 [2564:c07] startDownload:7
2013-09-02 06:45:22.099 [2564:c07] imageLoaderDidFinishDownloading:7
2013-09-02 06:45:22.104 [2564:c07] startDownload:8
2013-09-02 06:45:22.163 [2564:c07] imageLoaderDidFinishDownloading:8

滚动到项目 10 到 19 后:

2013-09-02 06:45:26.212 [2564:c07] loadImagesForOnscreenRows1:8
2013-09-02 06:45:26.212 [2564:c07] loadImagesForOnscreenRows1:0
2013-09-02 06:45:26.212 [2564:c07] loadImagesForOnscreenRows1:1
2013-09-02 06:45:26.212 [2564:c07] loadImagesForOnscreenRows1:6
2013-09-02 06:45:26.213 [2564:c07] loadImagesForOnscreenRows1:2
2013-09-02 06:45:26.213 [2564:c07] loadImagesForOnscreenRows1:3
2013-09-02 06:45:26.213 [2564:c07] loadImagesForOnscreenRows1:4
2013-09-02 06:45:26.213 [2564:c07] loadImagesForOnscreenRows1:5
2013-09-02 06:45:26.213 [2564:c07] loadImagesForOnscreenRows1:7
2013-09-02 06:45:26.214 [2564:c07] loadImagesForOnscreenRows2:8
2013-09-02 06:45:26.214 [2564:c07] loadImagesForOnscreenRows2:0
2013-09-02 06:45:26.214 [2564:c07] loadImagesForOnscreenRows2:1
2013-09-02 06:45:26.214 [2564:c07] loadImagesForOnscreenRows2:6
2013-09-02 06:45:26.214 [2564:c07] loadImagesForOnscreenRows2:2
2013-09-02 06:45:26.215 [2564:c07] loadImagesForOnscreenRows2:3
2013-09-02 06:45:26.215 [2564:c07] loadImagesForOnscreenRows2:4
2013-09-02 06:45:26.215 [2564:c07] loadImagesForOnscreenRows2:5
2013-09-02 06:45:26.215 [2564:c07] loadImagesForOnscreenRows2:7

正如您在滚动后看到的,项目可见索引路径确实保持不变。有没有其他人遇到过这个或解决方案的想法?还是我理解了 collectionview 的某些原理错误?

非常感谢!亲切的问候,简

最佳答案

如果您的目标是 iOS 8.0 及更高版本,您应该使用 collectionView:willDisplayCell:forItemAtIndexPath: 开始下载。如果使用 iOS 7.0,您应该继续使用 collectionView:cellForItemAtIndexPath:

在您的 imageLoaderDidFinishDownloading: 回调中,您应该检查相关索引路径是否仍然可见。如果是,则检索相应的单元格并更新其 ImageView 。如果单元格不可见,那么您的工作就完成了。为每个图像完成调用 -reloadData 会做很多昂贵的工作,如果您的用户当前正在滚动表格并且您重置其内容,则可能会出现严重的 UX 问题。您还可能多次执行 UIImageJPEGRepresentation() 工作,如果您在 imageLoaderDidFinishDownloading: 中执行一次此工作然后缓存它,这将有助于提高滚动性能。

因为看起来回调发生在后台线程上,所以请确保您只从主线程操作 UICollectionView

关于ios - UICollectionView indexPathsForVisibleItems 不更新新的可见单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18595421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com