[ios] UICollectionView 애니메이션 데이터 변경

내 프로젝트에서 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는 애니메이션을 적용하지 않으며 UIView 애니메이션 블록에 넣을 때 안정적으로 수행하지도 않습니다. UICollecitonView performBatchUpdates 블록에 있기를 원하므로 다음과 같은 것을 시도하십시오.

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


답변

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

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

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

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


답변

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

[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)


답변

Swift 사용자의 경우 collectionview에 섹션이 하나만있는 경우 :

self.collectionView.performBatchUpdates({
                    let indexSet = IndexSet(integersIn: 0...0)
                    self.collectionView.reloadSections(indexSet)
                }, completion: nil)

https://stackoverflow.com/a/42001389/4455570에서 볼 수 있듯이


답변

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];


답변

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

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

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


답변