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.