UICollectionView 애니메이션 데이터 변경


83

내 프로젝트에서 UICollectionView를 사용하여 아이콘 그리드를 표시합니다.

사용자는 NSSortDescriptor가 다른 코어 데이터에서 가져 오기를 호출하는 세그먼트 화 된 컨트롤을 클릭하여 순서를 변경할 수 있습니다.

데이터의 양은 항상 동일하며 다른 섹션 / 행으로 끝납니다.

- (IBAction)sortSegmentedControlChanged:(id)sender {

   _fetchedResultsController = nil;
   _fetchedResultsController = [self newFetchResultsControllerForSort];

   NSError *error;
   if (![self.fetchedResultsController performFetch:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }

   [self.collectionView reloadData];
}

문제는 reloadData가 변경 사항을 애니메이션하지 않고 UICollectionView가 새 데이터로 팝업된다는 것입니다.

변경 전후에 셀의 indexPath를 추적하고 [self.collectionView moveItemAtIndexPath : toIndexPath :]를 사용하여 변경 애니메이션을 수행해야합니까? 아니면 더 나은 방법이 있습니까?

나는 collectionViews를 서브 클래 싱하는 것에 많은 것을 얻지 않았으므로 어떤 도움이 될 것입니다 ...

고마워, 빌.


reloadData애니메이션 블록에서 해당 호출을 래핑 해 보셨습니까 ?
— 사이먼

답변:


71

reloadData는 애니메이션을 적용하지 않으며 UIView 애니메이션 블록에 넣을 때 안정적으로 수행하지도 않습니다. UICollecitonView performBatchUpdates 블록에 있기를 원하므로 다음과 같은 것을 시도하십시오.

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
    // do something on completion 
}];

5
네, 작동하는 것 같지만 섹션 번호를 저장 한 경우에만 ... 그렇지 않으면 "잘못된 섹션 수입니다. 업데이트 후 컬렉션보기에 포함 된 섹션 수 (10)는 다음 수와 같아야합니다. 업데이트 전에 컬렉션 뷰에 포함 된 섹션 (16) ". 섹션을 수동으로 삽입 / 삭제해야합니다 ... 어쨌든 수락했습니다! 감사.
— Nimrod7

1
"수동"이란 UICollectionView의 insertSections / moveSection : toSection / deleteSections 호출을 통해 의미합니까? 또는 다른 것? (죄송합니다. 지금까지 UICollectionView를 사용하면 섹션 수가 고정되어 있습니다.)
— Stripes

1
예 이러한 방법을 통해 ... 생각을 구현하기는 조금 까다로운, 당신은 이전과 업데이트 후 삽입 또는 이동 제거 어떤 그림 ... indexpaths을 기억해야
— Nimrod7

12
이것은 내 한 섹션 컬렉션 뷰에서 작동하지 않았습니다. 오류가 발생하지 않았지만 애니메이션도 적용되지 않았습니다. 대체 -reloadSections:하면 효과가 있습니다.
— paulmelnikow

9
이 대답은 정확하지 않습니다. 내 경우에는 performBatchUpdates에 reloadData를 넣으면 앱이 충돌하고 셀 수가 전후가 같지 않다고 말합니다. reloadSections를 사용하여 내 문제를 해결했습니다. Apple의 문서는 또한 애니메이션 블록에서 reloadData를 호출하지 않음을 나타냅니다
— Wingzero

145

포장 -reloadData에이 -performBatchUpdates:애니메이션에 하나의 섹션 콜렉션 뷰의 원인이하지 않는 것 같습니다.

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:nil];

그러나이 코드는 다음과 같이 작동합니다.

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];

9
문서 참고 : 항목이 삽입 또는 삭제되는 애니메이션 블록 중간에서 데이터 다시로드 메서드를 호출해서는 안됩니다. 삽입 및 삭제는 자동으로 테이블의 데이터가 적절하게 업데이트되도록합니다.
— Raphael Oliveira 2014 년

나는 이것이 정답이어야한다고 생각한다. 이것은 나를 위해 일했기 때문입니다. 나는 단 하나의 섹션을 가지고 있으며 이것은 정답이 아닙니다.
— Mahesh Agrawal

삽입하는 경우에도 작동하지 않습니다. 정렬 애니메이션을 재정의합니다.
— Andres Canella

3
self.collectionView performBatchUpdates전화를 걸 필요가 없다는 점에 주목할 가치가 있습니다.reloadSections애니메이션을 얻기 위해 . 실제로이 performBatchUpdates호출로 인해 경우에 따라 의도하지 않은 깜박임 / 셀 크기 조정 문제가 발생할 수 있습니다.
— 폴 포피엘

1
또는 [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; reloadSections컬렉션보기 또는 테이블보기에서 애니메이션으로 그렇게 할 수 있습니다.
— bauerMusic

67

이것은 모든 섹션의 다시로드를 애니메이션하기 위해 수행 한 작업입니다.

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];

스위프트 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)


3

performBatchUpdates:completion:블록 내부의 전체 컬렉션 뷰를 다시로드하면 iOS 9 시뮬레이터에서 글리치 애니메이션이 발생합니다. UICollectionViewCell삭제하려는 특정 항목 이 있거나 인덱스 경로가 deleteItemsAtIndexPaths:있는 경우 해당 블록에서 호출 할 수 있습니다. 를 사용하여 deleteItemsAtIndexPaths:부드럽고 멋진 애니메이션을 만듭니다.

UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];

1
제 경우에는 크래시 문제를 해결 한 것을 언급하고 싶습니다. 컬렉션 뷰에서 performUpdates를 호출하기 전에 데이터 소스 (예 : 섹션 / 항목 수)를 업데이트하십시오.
— ViruMax

애니메이션은 다른 작업에서 가져온 것입니다. reloadData에 대한 애니메이션이 있으며 어떤 상황에서도 없었습니다. insertItems는 오름차순으로 삽입하고 업데이트 후에 수행됩니다. deleteItems는 그 반대입니다.
— James Bush

1

도움말 텍스트는 다음과 같습니다.

컬렉션 뷰의 모든 항목을 다시로드하려면이 메서드를 호출합니다. 이렇게하면 컬렉션 뷰가 현재 보이는 항목을 모두 버리고 다시 표시합니다. 효율성을 위해 컬렉션보기에는 표시되는 셀과 보조보기 만 표시됩니다. 다시로드의 결과로 컬렉션 데이터가 축소되면 컬렉션 뷰는 그에 따라 스크롤 오프셋을 조정합니다. 항목이 삽입되거나 삭제되는 애니메이션 블록 중간에서이 메서드를 호출하면 안됩니다. 삽입 및 삭제는 자동으로 테이블의 데이터가 적절하게 업데이트되도록합니다.

핵심 부분은 "컬렉션 뷰가 현재 보이는 항목을 버리는 원인"이라고 생각합니다. 폐기 한 아이템의 움직임을 어떻게 애니메이션할까요?


정확하지 않습니다. reloadData는 애니메이션이없는 이중 작업입니다. 먼저 삭제 작업이고 삽입 작업입니다.
— James Bush
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.