मेरे पास एक संग्रह दृश्य के साथ व्यू कंट्रोलर है। जब दृश्य लोड होता है, दृश्यमान कक्ष (9 कोशिकाएं) सही ढंग से दिखाए जाते हैं। जब मैं स्क्रॉल करता हूं, तो मैं पार्टनरवॉलव्यू व्यू के लिए indexPathsForVisibleItems को कॉल करके loadImagesForOnscreenRows के साथ संग्रह दृश्य में दृश्यमान आइटम लोड करना चाहता हूं। लेकिन जब loadImagesForOnscreen सूचकांक देता है PathsForVisibleItems में इसके पहले 9 कक्ष होते हैं, भले ही कक्ष 10 से 18 स्क्रीन पर दिखाई दे। कोड मैं का उपयोग करें:UICollectionView indexPathsForVisibleItems नई दृश्यमान कोशिकाओं को अपडेट नहीं करते
#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
मदों की प्रारंभिक शो 19 आइटम 10 लोगों को स्क्रॉल करने के बाद:
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
जैसा कि आप स्क्रॉलिंग के बाद देख सकते हैं, आइटम दिखाई देने वाले इंडेक्स पथ समान रहते हैं। क्या किसी और को इसका समाधान हुआ है या समाधान के लिए एक विचार है? या क्या मैं संग्रहदृश्य के कुछ सिद्धांत को गलत समझ रहा हूं?
अग्रिम में बहुत धन्यवाद! दयालु संबंध, जनवरी
मुझे 'loadImagesForOnscreenRows' का उद्देश्य नहीं मिला है। 'CellForRowAtIndexPath' में आप छवि सेट करते हैं तो यह उपलब्ध है। अन्यथा, 'imageLoaderDidFinishDownloading' में आप इंडेक्स पथ को फिर से लोड कर सकते हैं, जो' cellForRowAtIndexPath' को फिर से कॉल करेगा या आप छवि पर सीधे स्क्रीन पर छवि को सेट कर सकते हैं। क्या वह इसे कवर नहीं करेगा? –
हाय टिमोथी, 'cellForRowAtIndexPath' दृश्य में दिखाई देने वाली कोशिकाओं को लोड करता है, मेरे मामले में पहले नौ में। जब मैं स्क्रॉल करना शुरू करता हूं, तो आगामी कक्षों को भरना नहीं होगा, इसके बजाय 'scrollViewDidEndDragging' कहा जाता है, जो' loadImagesForOnscreenRows' को कॉलव्यूज़ में कॉल करेगा। इस फ़ंक्शन में मैं इंडेक्सपैथ प्राप्त करना चाहता हूं, 'इंडेक्सपाथ्सफॉरविज़िबल इटम्स', जो दृश्यमान हैं, और छवियों को डाउनलोड करना शुरू करने के बाद, डाउनलोड होने के बाद, इंडेक्सपाथ को पुनः लोड करें। लेकिन 'indexPathsForVisibleItems' हमेशा पहले नौ लौटाता है। या मैं कुछ पूरी तरह गलत कर रहा हूँ। तालिकाओं के साथ यह इस तरह से ठीक काम करता है। –
जिन कोशिकाओं में छवियां नहीं हैं, वे आम तौर पर उस सेल के लिए डाउनलोड पूर्ण होने पर अलग-अलग भर जाएंगे, जो आपके मामले में 'imageLoaderDidFinishDownloading' में होगी। यह देखते हुए, मुझे 'loadimageforOnscreenRows' का बिंदु नहीं मिलता है। दूसरे शब्दों में, आप 'imageLoaderDidFinishDownloading' में सेल क्यों भर रहे हैं? –