Ho un ViewController con un CollectionView all'interno. Quando la vista viene caricata, le celle visibili (9 celle) vengono visualizzate correttamente. Quando scorro verso il basso, voglio caricare gli elementi visibili nella collectionview con loadImagesForOnscreenRows chiamando l'indicePathsForVisibleItems per partnerCollectionView. Ma quando loadImagesForOnscreenRows indexPathsForVisibleItems ha sempre le prime 9 celle in esso, anche quando le celle da 10 a 18 dovrebbero essere visibili sullo schermo. Il codice che uso è:UICollectionView indexPathsForVisibleItems non aggiorna nuove celle visibili
#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
e questo risultato in uscita:
spettacolo iniziale di elementi visibili
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
Dopo lo scorrimento al punto 10 a 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
Come puoi vedere dopo lo scorrimento, i percorsi degli indici visibili rimangono invariati. Qualcun altro ha incontrato questo o un'idea per una soluzione? O sono in grado di interpretare in modo errato qualche principio di collectionview?
Molte grazie in anticipo! Cordiali saluti, gen
Non ho lo scopo di 'loadImagesForOnscreenRows'. In 'cellForRowAtIndexPath' imposti l'immagine se è disponibile. Altrimenti, in 'imageLoaderDidFinishDownloading' puoi ricaricare il percorso dell'indice, che chiamerà di nuovo' cellForRowAtIndexPath' o puoi impostare l'immagine direttamente sulla cella se è ancora sullo schermo. Non lo coprirebbe? –
Hi Timothy, 'cellForRowAtIndexPath' carica le celle che sono visibili nella vista, nel mio caso le prime nove. Quando comincio lo scorrimento, le celle successive non verranno compilate, ma viene chiamato 'scrollViewDidEndDragging', che chiamerà' loadImagesForOnscreenRows', come in tableviews. In questa funzione voglio ottenere i percorsi index, 'indexPathsForVisibleItems', che sono visibili e iniziare a scaricare le immagini, una volta scaricati, ricaricare i percorsi degli indici. Ma 'indexPathsForVisibleItems' restituisce sempre i primi nove. O sto facendo qualcosa di completamente sbagliato. Con le tabelle funziona così in questo modo. –
Le celle che non dispongono di immagini in genere vengono compilate singolarmente al termine del download per quella cella, che nel tuo caso si verifica in "imageLoaderDidFinishDownloading". Detto questo, non ho capito "loadimageforOnscreenRows". In altre parole, perché non stai compilando la cella in 'imageLoaderDidFinishDownloading'? –