具有多个子类UICollectionViewCell的UICollectionView [英] UICollectionView with Multiple subclassed UICollectionViewCell

查看:118
本文介绍了具有多个子类UICollectionViewCell的UICollectionView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have multiple sections in my UICollectionView grouped by "datasetType".

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

I also have a custom UICollectionViewCell for each section.

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

How can I determine which custom UICollectionViewCell I need in the cellForItemAtIndexPath method?

我的第一个是基于 [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];
}

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

But I'm running to an issue where its trying to load the wrong dataset cell.

这应该工作,我需要查看错误的位置吗?或者我这部分做错了吗?

Should this work and I need to look else where for the error? Or am I doing this part wrong?

编辑:

我应该做些什么。问题是索引没有排队。

What I have should work. The issue is the index's do not line up.

对于我的fetchedResultsController,我创建它:

For my fetchedResultsController, I create it as:

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

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

This fetches them and sorts them by name. I use Magical Record in the project, and I use its fetch controller cause I can not get the Core Data fetch controller to work:

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的背景。 / boggle

The fetchRequest I do in this code returns the entities, its once I put it through the fetch controller it always returns nothing. I don't think it likes MR's context. /boggle

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

When I try to fill each subclassed UICollectionViewCell (DatasetACell, DataseetBCell, etc), it can retrieve the wrong data cell.

所以在indexPath(0,0), NSFetchedResultsController

So at indexPath (0,0), in the NSFetchedResultsController

[self.fetchedResultsController sections] objectAtIndex:indexPath]

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

will return a datasetA entity while the collection view for the same index

[collectionView dequeueReusableCellWithReuseIdentifier:datasetACell forIndexPath:indexPath] 

返回datasetBCell。

returns a datasetBCell.

NSFetchedResultsController 存在问题,而 [collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath ] 未排序。

There is an issue with the NSFetchedResultsController is sorted while the [collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath] is not sorted.

完整代码:

-(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),代码认为它是数据集B,但实际上是数据集。在第二个指数(1,0)中则相反;代码认为它是数据集A但是数据集B。在这个集合中,有1个数据集B和许多数据集A.

For the first index (0,0), the code thinks it is a DatasetB but is actually a DatasetA. In the second index (1,0) its the opposite; the code thinks its a DatasetA but is a DatasetB. In this set, there is 1 DatasetB and many DatasetA's.

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

When the fetch controller sorts it, it sorts Dataset B first. The collection view is expecting a DatasetB but the fetch controller is returning a DatasetA for the same index.

推荐答案

看来有一个需要排序的排序问题。

It appears there is an issue with the sorting which needs to be sorted.

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

But my question is why are you switching on the section name? Why not just switch on the class of the item?

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
}

至少这样你就没有有排序的问题

At least this way you don't have issues with the sorting

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

You probably want to correct your fetch request so that you sort by datasetType and then by 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;
}






也是你自己的原因make fetchResultsController 可能没有返回任何内容是因为你没有自己用fetch请求执行fetch,你可以通过fetchedResultsController来实现,比如


Also the reason your self made fetchResultsController probably returned nothing is because you don't perform the fetch with the fetch request yourself, you do it through the fetchedResultsController like

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

这篇关于具有多个子类UICollectionViewCell的UICollectionView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆