내부에 CollectionView가있는 ViewController가 있습니다. 뷰가로드되면 보이는 셀 (9 셀)이 올바르게 표시됩니다. 아래로 스크롤하면 partnerCollectionView에 대한 indexPathsForVisibleItems를 호출하여 loadImagesForOnscreenRows를 사용하여 collectionview에 표시된 항목을로드하려고합니다. 그러나 loadImagesForOnscreenRows를 사용하면 indexPathsForVisibleItems에 셀 10 ~ 18을 화면에 표시해야하는 경우에도 첫 번째 9 개의 셀이 있습니다. 내가 사용하는 코드는 다음과 같습니다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
그리고 출력이 결과 :
19 항목 10로 스크롤 한 후 표시되는 항목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
의
초기 쇼 :
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 잘못 원칙을 unsterstanding 무엇입니까?
미리 감사드립니다. 친절한 답변, Jan
'loadImagesForOnscreenRows'의 목적을 얻지 못했습니다. 'cellForRowAtIndexPath'에 이미지가 있으면 그것을 설정합니다. 그렇지 않으면'imageLoaderDidFinishDownloading'에서 인덱스 경로를 다시로드 할 수 있습니다.이 경로는'cellForRowAtIndexPath'를 다시 호출하거나 화면에 여전히있는 경우 직접 셀에 이미지를 설정할 수 있습니다. 그걸 다 커버하지 않을 래? –
안녕하세요, Timothy,'cellForRowAtIndexPath'는보기에 표시되는 셀을로드합니다. 제 경우에는 처음 9 개입니다. 스크롤을 시작하면 다가오는 셀이 채워지지 않고 대신에'scrollViewDidEndDragging'이 호출됩니다.이 뷰는 tableviews와 같이'loadImagesForOnscreenRows'를 호출합니다. 이 함수에서 나는 볼 수있는 인덱스 경로 인'indexPathsForVisibleItems'를 얻고, 일단 이미지를 다운로드하기 시작하면, 일단 다운로드되면, indexpath를 다시로드합니다. 그러나'indexPathsForVisibleItems'는 항상 처음 9 개를 반환합니다. 아니면 완전히 잘못된 것을하고 있습니다. 테이블을 사용하면이 방법으로 잘 작동합니다. –
이미지가없는 셀은 일반적으로 해당 셀의 다운로드가 완료되면 개별적으로 채워집니다. 이는 'imageLoaderDidFinishDownloading'에서 발생합니다. 이것을 감안할 때, 나는'loadimageforOnscreenRows'의 요점을 얻지 못했습니다. 즉, 왜'imageLoaderDidFinishDownloading'에서 셀을 채우지 않았습니까? –