具有多个子类UICollectionViewCell的UICollectionView

Pad*_*215 9 objective-c nsfetchedresultscontroller ios magicalrecord uicollectionview

我的UICollectionView中有多个部分按"datasetType"分组.

我还为每个部分都有一个自定义的UICollectionViewCell.

如何确定方法中UICollectionViewCell需要哪个自定义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];
}
Run Code Online (Sandbox Code Playgroud)

但我正在尝试加载错误的数据集单元格.

这应该工作,我需要看看错误在哪里?或者我这部分做错了吗?

编辑:

我有什么应该工作.问题是索引没有排队.

对于我的fetchedResultsController,我将其创建为:

_fetchedResultsController = [Dataset MR_fetchAllSortedBy:NAME
                                               ascending:TRUE
                                           withPredicate:predicate
                                                 groupBy:@"datasetType"
                                                delegate:self.fetchedResultsController.delegate
                                               inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
Run Code Online (Sandbox Code Playgroud)

这将获取它们并按名称对它们进行排序.我在项目中使用Magical Record,并使用其fetch控制器,因为我无法使Core Data fetch控制器工作:

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;
Run Code Online (Sandbox Code Playgroud)

我在这段代码中执行的fetchRequest返回实体,一旦我通过fetch控制器,它总是返回任何内容.我不认为它喜欢MR的背景./惊奇

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

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

[self.fetchedResultsController sections] objectAtIndex:indexPath]
Run Code Online (Sandbox Code Playgroud)

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

[collectionView dequeueReusableCellWithReuseIdentifier:datasetACell forIndexPath:indexPath] 
Run Code Online (Sandbox Code Playgroud)

返回datasetBCell.

如果未排序,NSFetchedResultsController则排序存在问题[collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath].

完整代码:

-(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
    }
}
Run Code Online (Sandbox Code Playgroud)

日志:

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
Run Code Online (Sandbox Code Playgroud)

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

当获取控制器对其进行排序时,它首先对数据集B进行排序.集合视图需要数据集B,但是获取控制器正在返回相同索引的数据集.

Pau*_*l.s 5

看来排序存在问题需要排序.

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

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
}
Run Code Online (Sandbox Code Playgroud)

至少这种方式你没有排序问题

您可能想要更正您的提取请求,以便您按排序datasetType然后排序name.

- (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;
}
Run Code Online (Sandbox Code Playgroud)

你自己造成的原因fetchResultsController可能是什么都没有,因为你自己没有用获取请求执行获取,你通过fetchedResultsController来做到这一点

if ([fetchedResultsController performFetch:&error]) {
   //...
Run Code Online (Sandbox Code Playgroud)