2013-06-20 3 views
0

iOS에서 UICollectionview를 다시로드하려고 할 때 probem이 있습니다.UICollectionview를 언로드하고 새로 고침 하시겠습니까?

게임의 레벨을 표시하는 데 사용하고 있습니다.

콜렉션 뷰는 10 개의 셀로 구성됩니다. 레벨이 잠금 해제되어 있는지 여부에 따라 셀의 내용이 달라집니다. 레벨이 잠금 해제되어 있으면 셀이 레벨 (사용자 정의 UIView)을 표시하고, 그렇지 않으면 이미지를 표시합니다. 이 작업을 위해 개별 셀 식별자를 만들어야했고 모든 것이로드시 완벽하게 표시됩니다.

내 문제는 사용자가 잠금 해제 된 수준을 재생하고 다음 수준을 잠금 해제 할 때입니다. 사용자가 게임보기에서 레벨 선택보기로 다시 이동하면 셀이 올바르게 다시로드되지 않습니다. 사용자 정의보기가 있어야하며 이미지가 올바르게 표시됩니다.

viewWillAppear의 레벨로 배열을 언로드 한 다음 [collectionview reloadData]를 호출하고 레벨을로드하고 collectionview를 다시로드하려고 시도했지만 도움이되지 않습니다.

전체 콜렉션 뷰를 비우고 뷰가 표시되면 어떻게 셀 식별자를 다시 만들 수 있습니까?

감사합니다.

-EDIT! 코드로 업데이트 -

그리고 항목의 셀에

-(void)viewWillAppear:(BOOL)animated { 
[super viewWillAppear:YES]; 

levelsArray = nil; 
puzzlesArray = nil; 

levelsArray = [[NSMutableArray alloc]init]; 
puzzlesArray = [[NSMutableArray alloc]init]; 

[collectionView reloadData]; 

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
NSData *data = [defaults objectForKey:@"puzzles"]; 
puzzlesArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

if ([puzzlesArray count] == 0) { 
    [self.navigationController popViewControllerAnimated:YES]; 
} 
else { 
    NSLog(@"%i puzzles loaded", [puzzlesArray count]); 

    //Get alle puzzles for the current category 
    for (Puzzle *puzzle in puzzlesArray) { 

     if ([[[NSUserDefaults standardUserDefaults]objectForKey:@"Category"] isEqualToString:[puzzle categoryName]]) { 
      [levelsArray addObject:puzzle]; 
     } 

    } 

} 

NSLog(@"View will appear"); 
[collectionView reloadData]; 

} 롭의 제안에 라인에서 인덱스 경로

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; { 

    BOOL isUnlocked = [self isPuzzleUnlocked:[indexPath row]]; 

    if ([[NSUserDefaults standardUserDefaults]boolForKey:@"u"] == YES) { 
     isUnlocked = YES; 
    } 

    [self.collectionView registerNib:[UINib nibWithNibName:@"CVCell" bundle:nil] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d", kCellReuseIdentifier, indexPath.row]]; 

    CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d", kCellReuseIdentifier, indexPath.row] forIndexPath:indexPath]; 

[cell setPuzzleInfo:[levelsArray objectAtIndex:[indexPath row]] unlocked:isUnlocked]; 

     return cell; 

} 
+1

당신은 "사용자 지정보기"는 비어 있지만, "이미지가 제대로 표시"라고 . 나는이 두 진술을 어떻게 조화 시킬지 모른다. 그러나 귀하의 질문에 대한 답변으로, 'reloadData' _는 올바른 기술입니다. 다양한 'UICollectionViewDataSource'에 로그 문이나 디버그 중단 점을 넣고 올바른 값이보고되는지 확인합니다. 이 컬렉션 뷰는 원래 올바르게 작동했지만 레벨을 "잠금 해제"한 후에 올바르게 작동하지 않았습니까? – Rob

+0

의견을 남겨 주셔서 감사합니다. 혼란에 빠져서 죄송 합니다만, 다시로드 할 때 변경되는 셀이 바뀌지 않는 것과 같습니다. 데이터에서 NSLog를 시도했지만 올바른 것입니다. 그러나 세포가 한번 만들어지면 WillAppear의 관점에서 "재창조"되지 않은 것처럼 보입니다. 뷰를 종료하고 다시 열 때 올바르게 나타납니다. 문제는 세포가 여전히 메모리에 있고 다시로드되지 않는다는 것입니다. – CCDEV

+0

일반적으로'viewWillAppear' 또는'viewDidAppear'에'reloadData' ('super'를 호출 한 후)를 호출하는 코드를 작성합니다. 자신을 반복하기 위해서'numOfItemsInSection'과'cellForItemAtIndexPath'에 로그 문을 넣었습니다. 그래서 뷰가 다시 나타나면'reloadData'가 제대로 호출되는지 확인하고 그 시점에서 모델 구조의 다양한 값을 확인할 수 있습니다 . – Rob

답변

1

에서.

-(void)viewWillAppear { 
    [super viewWillAppear]; 
    [self.collectionView reloadData]; 
} 

cellForItemAtIndexPath에서 당신은 단순히 항목이 잠금 해제인지 여부를 확인하고 적절한 이미지 또는 사용자 정의 셀을 표시해야합니다.

그게 전부입니다. 컬렉션보기를 다시 만들려면 이 아니고이 필요합니다.

게임 컨트롤러와 레벨 컨트롤러에 레벨을 모델링하는 데이터에 대한 액세스 권한을 부여함으로써 MVC (model-view-controller) 디자인 패턴을 존중할 수 있습니다. 게임에서 일어나는 일이 새로운 레벨의 잠금을 해제하면이 데이터가 변경되어야합니다. 컬렉션보기는 표시되기 직전에이 데이터를 기반으로 자체적으로 다시로드되어야합니다.

편집 : 당신도 당신 생각 reloadData 이전과 동일 세포/항목을받을 경우

, 이것은 구성이 올바르게 설정되지 않음을 의미합니다. 열쇠는 두 상태를 모두 설정unlocked-reloadData 명시 적으로 변경된 항목을 업데이트합니다.

EDIT2 :

모두 당신의 itemForRowAtIndexPath 방법은 엉망이된다. registerNib에 대한 전화는 여기에 속하지 않습니다. 초기화 프로세스 중에 호출되어야합니다. 스토리 보드를 사용한다면 전혀 필요하지 않습니다.

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv 
        cellForItemAtIndexPath:(NSIndexPath *)indexPath; { 

    PuzzleInfo *puzzleObject = [dataArray objectAtIndex:indexPath.row]; 
    // you can use your more complicated data structure here, but 
    // have one object, dictionary, array item, etc. that has the info you need 

    NSString *identifier = puzzleObject.unlocked ? kUnlockedCell : kLockedCell; 
    CVCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier 
      forIndexPath:indexPath]; 

    if (puzzleObject.unlocked) { 
     // configure the unlocked cell 
    } 
    else { 
     // configure the locked cell 
    } 

    return cell; 
} 
+0

답장을 보내 주셔서 감사합니다. Mundi,하지만 이미 그 일을하고 있습니다. 내가하는 일을 보여주기 위해 원래 질문에 코드를 추가했습니다. 나는 이것이 문제가 될 수 있다고 생각한다. "CVCell * cell = (CVCell *) [collectionView dequeueReusableCellWithReuseIdentifier : [NSString stringWithFormat : @"% @ % d ", kCellReuseIdentifier, indexPath.row] forIndexPath : indexPath];" 셀 식별자를 기억하고 제대로 다시로드되지 않기 때문에? – CCDEV

-3

내가 그것을 고정 :

다음은 사용해야하는 간단한 프레임 워크입니다!

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; { 
NSLog(@"CALLED"); 
BOOL isUnlocked = [self isPuzzleUnlocked:[indexPath row]]; 

if ([[NSUserDefaults standardUserDefaults]boolForKey:@"u"] == YES) { 
    isUnlocked = YES; 
} 
int rand = arc4random() % 99001; 
[self.collectionView registerNib:[UINib nibWithNibName:@"CVCell" bundle:nil] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d%i", kCellReuseIdentifier, indexPath.row, rand]]; 

CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d%i", kCellReuseIdentifier, indexPath.row, rand] forIndexPath:indexPath]; 
[cell setPuzzleInfo:[levelsArray objectAtIndex:[indexPath row]] unlocked:isUnlocked]; 

    return cell; 

}

아니 매우 메모리 effecient 솔루션 (또는 우아한),하지만 작동합니다. 각 셀에 임의의 숫자를 추가하면 매번 다시 작성해야합니다. 언제 까지나 난 단지 내가 괜찮을 것입니다 생각 collectionview 10 개 세포 .. 모든 도움을

덕분에이 같이]

+0

이것은 좋은 해결책이 아닙니다. 적어도 "수정 사항"은 아닙니다. 현재 작동한다고해도, 깨지기 쉽습니다. cellForItem에 임의의 셀 식별자를 작성 중입니다 ... 설명을 보려면 수정 된 답변을 참조하십시오. – Mundi

+0

안녕 Mundi, 네, 이제는 이상적인 솔루션을 알고 있습니다. 문제는 당신의 대답이 문제를 해결하지 못한다는 것입니다. 콜렉션 뷰 버그인지 모르지만 데이터는 정확하지만 잘못 표시됩니다. 셀 식별자가 다시 만들어 지므로이 문제가 해결됩니다. Locked Unlocked 데이터의 NSLog를 수행하면 올바르게 표시되지만 [collectiionview reloadData]에 다시로드되지 않습니다. 왜 이것이 깨질 지 모르겠다. ARC를 사용하고 매번 문제가 발생하지 않는 셀을 재현하고 있습니까? 성능은 유일한 문제이지만 10-15 개의 셀만 있으면 문제가되지 않습니다. – CCDEV

+0

이 경우 랜덤 셀 식별자를 만드는 것은 여전히 ​​터무니 없습니다. 대기열에서 제외하지 않으면 동일한 효과를 얻을 수 있습니다. – Mundi

관련 문제