UICollectionView与多个子类UICollectionViewCell

我有我的UICollectionView按“datasetType”分组的多个部分。

我也有每个部分的自定义UICollectionViewCell。

我如何确定在cellForItemAtIndexPath方法中需要哪个自定义的cellForItemAtIndexPath

我的第一个虽然是基于[sectionInfo name]

 id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section]; if ([[sectionInfo name] isEqualToString:@"DatasetA"]) { DatasetACell *datasetACell = [collectionView dequeueReusableCellWithReuseIdentifier:datasetACellIdentifer forIndexPath:indexPath]; DatasetA *datasetA = [self.fetchedResultsController objectAtIndexPath:indexPath]; } 

但我遇到了一个问题,试图加载错误的数据集单元格。

如果这个工作,我需要看看其他地方的错误? 还是我做这个部分是错的?

编辑:

我有什么应该工作。 问题是索引不排队。

对于我的fetchedResultsController,我创build它为:

 _fetchedResultsController = [Dataset MR_fetchAllSortedBy:NAME ascending:TRUE withPredicate:predicate groupBy:@"datasetType" delegate:self.fetchedResultsController.delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; 

这会提取它们并按名称sorting。 我在项目中使用魔法logging,并使用其获取控制器,因为我无法让核心数据获取控制器工作:

 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Dataset" inManagedObjectContext:[NSManagedObjectContext MR_contextForCurrentThread]]; [fetchRequest setEntity:entity]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:NAME ascending:TRUE selector:@selector(caseInsensitiveCompare:)]; NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; NSError *error; NSArray *fetchedArray = [[NSManagedObjectContext MR_contextForCurrentThread] executeFetchRequest:fetchRequest error:&error]; NSLog(@"fetchedArray: %@", fetchedArray); NSFetchedResultsController *FRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_contextForCurrentThread] sectionNameKeyPath:nil cacheName:nil]; FRC.delegate = self; 

我在这段代码中执行的fetchRequest函数返回实体,一旦我把它放到fetch控制器,它总是不返回任何东西。 我不认为它喜欢MR的背景。 /惊奇

当我尝试填充每个子类UICollectionViewCell (DatasetCell,DataseetBCell等)时,它可以检索错误的数据单元格。

所以在indexPath(0,0),在NSFetchedResultsController

 [self.fetchedResultsController sections] objectAtIndex:indexPath] 

将返回一个datasetA实体,同时收集相同索引的视图

 [collectionView dequeueReusableCellWithReuseIdentifier:datasetACell forIndexPath:indexPath] 

返回一个数据集BCell。

[collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath]存在问题,而[collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath]未sorting。

完整代码:

 -(NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSPredicate *predicate = [NSPredicate predicateWithFormat:@"boundary.boundaryID == %@", self.dataseter.boundaryID]; _fetchedResultsController = [Dataset MR_fetchAllSortedBy:NAME ascending:TRUE withPredicate:predicate groupBy:@"datasetType" delegate:_fetchedResultsController.delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; return _fetchedResultsController; } -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section]; NSLog(@"indexPath: %@", indexPath); NSLog(@"[sectionInfo name]: %@", [sectionInfo name]); if ([[sectionInfo name] isEqualToString:SAVED_ANALYSIS]) { NSLog(@"section name is DATASET A"); DatasetCellA *datasetCellA = (DatasetCellA *)[collectionView dequeueReusableCellWithReuseIdentifier:datasetcellAIdentifier forIndexPath:indexPath]; DatasetA *datasetA = [self.fetchedResultsController objectAtIndexPath:indexPath]; NSLog(@"datasetA.id: %@", datasetA.id); NSLog(@"datasetA: %@", datasetA); // configure and return cell } else if ([[sectionInfo name] isEqualToString:EDITED_IMAGES]) { NSLog(@"section name is DATASET B"); DatasetCellB *datasetCellB = (DatasetCellB *)[collectionView dequeueReusableCellWithReuseIdentifier:datasetCellBIdentifer forIndexPath:indexPath]; DatasetB *datasetB = [self.fetchedResultsController objectAtIndex:indexPath]; NSLog(@"editedImage.id: %@", datasetB.id); NSLog(@"editedImage: %@", datasetB); // configure and return cell } } 

日志:

 2013-04-04 10:59:38.697 [2380:14003] indexPath: <NSIndexPath 0x19b645c0> 2 indexes [0, 0] 2013-04-04 10:59:38.697 [2380:14003] [sectionInfo name]: Dataset B 2013-04-04 10:59:38.697 [2380:14003] section name is DATASET B 2013-04-04 10:59:38.702 [2380:14003] datasetB.id: 1581 2013-04-04 10:59:38.703 [2380:14003] datasetB: <DatasetA: 0x1c193ac0> (entity: DatasetA; id: 0x16141bd0 <x-coredata://9313C8D3-0AA8-4F3F-B32D-F1F7843D4FA1/DatasetA/p168> ; data: { }) 2013-04-04 10:59:38.703 [2380:14003] indexPath: <NSIndexPath 0x19b64560> 2 indexes [1, 0] 2013-04-04 10:59:38.703 [2380:14003] [sectionInfo name]: Dataset A 2013-04-04 10:59:38.704 [2380:14003] section name is DATSET A 2013-04-04 10:59:38.709 [2380:14003] datasetA.id: 75 2013-04-04 10:59:38.709 [2380:14003] datasetA: <DatasetB: 0x1c15a830> (entity: DatasetB; id: 0x16141b30 <x-coredata://9313C8D3-0AA8-4F3F-B32D-F1F7843D4FA1/DatasetB/p165> ; data: { }) 2013-04-04 10:59:38.724 [2380:14003] -[DatasetB mode]: unrecognized selector sent to instance 0x1c15a830 2013-04-04 10:59:38.725 [2380:14003] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DatasetB mode]: unrecognized selector sent to instance 0x1c15a830' *** First throw call stack: (0x1c19012 0x1a3ee7e 0x1ca44bd 0x1c08bbc 0x1c0894e 0x80028 0xe862da 0xe878f4 0xe89b91 0x9d32dd 0x1a526b0 0x56cfc0 0x56133c 0x561150 0x4df0bc 0x4e0227 0x4e08e2 0x1be1afe 0x1be1a3d 0x1bbf7c2 0x1bbef44 0x1bbee1b 0x28cc7e3 0x28cc668 0x982ffc 0x1ebd 0x1de5) libc++abi.dylib: terminate called throwing an exception 

对于第一个索引(0,0),代码认为它是一个DatasetB,但实际上是一个DatasetA。 在第二个指数(1,0)中则相反; 该代码认为它是一个数据集A,但是是一个数据集B. 在这个集合中,有1个数据集B和许多数据集A.

当提取控制器对它进行sorting时,它首先对数据集B进行sorting。 集合视图期待一个DatasetB,但是获取控制器正在为同一个索引返回一个DatasetA。

看起来有一个需要sorting的sorting问题。

但是我的问题是,你为什么要切换部分名称? 为什么不打开该项目的类?

 id object = [self.fetchedResultsController objectAtIndexPath:indexPath]; if ([object isKindOfClass:[DatasetA class]] { // Do your DatasetCellA stuff } else if ([object isKindOfClass:[DatasetB class]) { // Do your DatasetCellB stuff } 

至less这样你就没有sorting问题

您可能需要更正您的获取请求,以便按datasetTypenamesorting。

 - (NSFetchedResultsController *)fetchedResultsController { if (!_fetchedResultsController) { return _fetchedResultsController; } NSFetchRequest *request = [[NSFetchRequest alloc] init]; request.entity = [Dataset MR_entityDescription]; request.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"datasetType" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO], ]; _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[NSManagedObjectContext MR_context] sectionNameKeyPath:@"datasetType" cacheName:nil]; NSError *error = nil; if (![_fetchedResultsController performFetch:&error]) { NSLog(@"Could not perform fetch %@", [error localizedDescription]); } _fetchedResultsController.delegate = <..your delegate..>; return _fetchedResultsController; } 

此外,你自己的fetchResultsController可能没有返回任何东西的原因是因为你自己不执行提取请求,你可以通过fetchedResultsController

 if ([fetchedResultsController performFetch:&error]) { //... 

没有更多的模型结构的知识,我不能更确定,但是这里呢…

我认为你的问题是,你期望search结果以某种方式sorting,但他们没有按照你期望的方式sorting。

数据集使用了groupBy:@"datasetType"子句,它定义了这些部分。 但是这些部分也将被groupBy键隐式sorting。 所以问题是:

你的模型中的这个datasetType键是什么,你期望它是什么? 显然你想按数据集名称sorting,但是datasetType是什么名字? 这是我相信问题所在的地方。 您正在检索错误的sorting顺序,因为您没有按数据集的名称进行分组。

PS:你有“DATSET A”和“DATASET B”…所以如果你确实按照数据集的名字进行分组的话,那么所有这些都是按照预期工作的……除了你的名字有错别字。

你显然在你的数据集名称中有一个错字:

 2013-04-04 10:59:38.704 [2380:14003] section name is DATSET A 

在DATSET A中缺less第二个“A”,这将在DATASET B之后sorting。

文字的危害。