9

내 UICollectionView에 "datasetType"으로 그룹화 된 여러 섹션이 있습니다.여러 하위 클래스가있는 UICollectionView UICollectionViewCell

또한 각 섹션에 대해 사용자 지정 UICollectionViewCell이 있습니다.

cellForItemAtIndexPath 방법에서 어떤 맞춤 UICollectionViewCell이 필요한지 어떻게 결정할 수 있습니까?

내 첫번째 생각이었다 [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 = [Dataset MR_fetchAllSortedBy:NAME 
               ascending:TRUE 
              withPredicate:predicate 
               groupBy:@"datasetType" 
               delegate:self.fetchedResultsController.delegate 
               inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; 

이 그들을 가져와 이름을 정렬 : 내 fetchedResultsController를 들어

, 나는로 만들 수 있습니다. 내가 코어 데이터가 작동하는 컨트롤러를 가져 얻을 수없는 컨트롤러 원인을 가져 내가 프로젝트에 마법 기록을 사용하고, 나는 그것을 사용

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를, 그 한 번 나는 그것을 넣어 가져 오기 컨트롤러를 통해 항상 아무것도 반환하지 않습니다. 나는 MR의 문맥을 좋아하지 않는다고 생각한다./boggle

서브 클래스 UICollectionViewCell (DatasetACell, DataseetBCell 등)을 채울 때 잘못된 데이터 셀을 검색 할 수 있습니다. 같은 인덱스

[collectionView dequeueReusableCellWithReuseIdentifier:datasetACell forIndexPath:indexPath] 

에 대한 콜렉션 뷰가 datasetBCell을 반환하면서 NSFetchedResultsController

[self.fetchedResultsController sections] objectAtIndex:indexPath] 

의 indexPath (0,0)에 따라서

는 datasetA 개체를 반환합니다.

[collectionView dequeueResuableCellwithReuseIdentifier:forIndexPath]이 정렬되지 않은 동안 NSFetchedResultsController이 정렬되는데 문제가 있습니다.

전체 코드 :

-(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 
    } 
} 

LOG : 최초의 인덱스 (0, 0)에 대한

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 

는 코드는이 DatasetB하지만 실제로 DatasetA입니다 생각한다. 두 번째 인덱스 (1,0)에서 그 반대; 코드는 DatasetA라고 생각하지만 DatasetB입니다. 이 집합에는 1 개의 DatasetB와 많은 DatasetA가 있습니다.

반입 컨트롤러가이를 정렬 할 때 먼저 데이터 세트 B를 정렬합니다. 컬렉션 뷰는 DatasetB를 기대하지만 가져 오기 컨트롤러는 동일한 인덱스에 대해 DatasetA를 반환합니다.좀 더 확실한, 그러나 여기 간다 수없는 모델 구조의 더 많은 지식없이

+0

다른 셀 유형에 대해 고유 한 재사용 식별자를 설정 했습니까? 당신이 가진 것은 꽤 많은 일을해야합니다. – dasblinkenlight

+0

그것이 제가 확인한 첫 번째 것입니다. – Padin215

+0

'NAME '이란 무엇입니까? –

답변

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 
} 

적어도이 방법은 name에 의해 다음 있도록 일종의 datasetType에 의해 요청을 가져오고.

- (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을 만든 이유는 아마 당신이 술책을 수행하는 자신을 요청 가져 오지 않기 때문에 아무것도 없다 반환, 당신은

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

좋아, 이것은 충돌을 방지합니다.올바른 셀을 사용하지만 DataseB 섹션에 DatasetA 셀이 있습니다. indexPath.section이 DatasetA이면 DatasetA 엔티티와 셀을 가져 와서 해당 섹션에 배치하십시오. 문제는 indexPath에 대한 것이므로 가져온 컨트롤러에서 올바른 데이터 집합 엔터티를 가져 오지 못합니다. – Padin215

+0

나는 당신이 당신의 정렬 순서를 바로 잡아야한다고 생각합니다. –

+0

그랬어! 고마워요! 나는 원래 애플 NSFetchedResultController 방법을 사용해 보았지만 작동하도록 만들지는 못했다. (Magical Record 메서드는 래퍼 였고 그들은 아무것도하지 않았다.) FRC 픽스는 사용자가 제안한 스위치 변경 사항과 함께 작동합니다. – Padin215

1

...

당신이 검색 결과가 특정한 방식으로 정렬 할 기대하는 문제가있다 생각하지만, 그들은 ' 당신이 그들을 기대하는 방식으로 정렬되지 않습니다.

데이터 세트는 섹션을 정의하는 groupBy:@"datasetType" 절을 사용합니다. 그러나 섹션은 groupBy 키에 의해 암시 적으로 정렬됩니다. 질문은 다음과 같습니다.

모델에 datasetType 키가 무엇입니까? 분명히 데이터 집합 이름별로 정렬하고 싶지만 datasetType 이름이 무엇입니까? 이것은 내가 문제가 있다고 믿는 곳입니다. 데이터 세트의 이름별로 그룹화하지 않기 때문에 잘못된 정렬 순서를 검색하고 있습니다.

추 신 : "DATSET A"와 "DATASET B"가 있습니다 ... 실제로 데이터 세트 이름별로 그룹화하는 경우 오타가있는 이름을 제외하면 예상대로 작동합니다.

+0

datasetType은 "datasetA"또는 "datasetB"값을 가진 NSString 값입니다. 따라서 각 섹션 내에서 모든 데이터 세트 A 또는 모든 데이터 세트 B가됩니다. 그룹화 된 것은'NSFetchedResultsController' init 메소드의'sectionNameKeyPath :'매개 변수와 같다고 생각합니다. 그래서 그들은 datasetType에 의해 그룹화되고 이름으로 정렬되어야합니다. 섹션이 이름순으로 정렬되어 있습니다. – Padin215

+0

그래서 섹션은 원하는 방식으로 이름순으로 정렬됩니다. – Rikkles

+0

오타가 아무 효과가 없습니다. 그것의 그냥 로깅 그 헤이, 나는 if ([[sectionInfo name] isEqualToString : SAVED_ANALYSIS)''에 대한 stmt를 입력했다. – Padin215

0

처럼 fetchedResultsController을 통해 그것을 할 당신 데이터 세트 이름에 오타가있는 것 같습니다.

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

ecset 'A'가 DATSET A에 없으면 데이터베이스 B를 따라 정렬합니다.

리터럴의 위험 요소입니다.

+0

그건 저를 일종의 이름을 바꾸는 유형이었습니다. 코드를 보면, NSLog가 stat. if를 DATASETA에 넣었다고 말하는 것입니다. – Padin215

+0

그래도 SAVED_ANALYSIS의 typo (복사하여 붙여 넣기?)가 동일한 경우이 효과가 있습니다. SAVED_ANALYSIS를 정의하는 코드는 게시되지 않으므로 확인하기가 어렵고 서로 다른 두 곳에서 일치해야하는 리터럴을 사용하는 것이 일반적인 문제입니다. :-) –

+0

코드'NSLog (@ "섹션 이름은 DATASET A"입니다.);는 로깅되어야합니다. 개념을 쉽게 이해할 수 있도록 개체의 이름을 변경했으며 로그의 이름을 변경했을 때 DATASETA 대신 DATSETA를 입력했습니다. 그 외에도'datasetA : '; "datasetA"는 거기에있는 것이고, 은 실제로로드 된 것입니다. – Padin215