UICollectionView는 reloadItemsAtIndexPaths가 호출 된 후 항목을 애니메이션합니다 (애니메이션 페이드).
이 애니메이션을 피할 수있는 방법이 있습니까?
iOS 6
답변:
iOS 7 이상을 타겟팅하는 경우 새로운 UIView
방법을 사용할 수 있습니다 performWithoutAnimation:
. 나는 후드 아래에서 이것이 여기에있는 다른 답변과 거의 같은 일을하고 있다고 생각합니다 (일시적으로 비활성화UIView
애니메이션 / 핵심 애니메이션 작업 )과 거의 동일하지만 구문은 훌륭하고 깨끗합니다.
특히이 질문에 대해서는 ...
목표 -C :
[UIView performWithoutAnimation:^{
[self.collectionView reloadItemsAtIndexPaths:indexPaths];
}];
빠른:
UIView.performWithoutAnimation {
self.collectionView.reloadItemsAtIndexPaths(indexPaths)
}
물론이 원칙은 변경 사항이 애니메이션 되지 않도록하려는 모든 상황에 적용될 수 있습니다 .
다음을 시도해 볼 수도 있습니다.
UICollectionView *collectionView;
...
[UIView setAnimationsEnabled:NO];
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];
}];
또한 performBatchUpdates
UIView 애니메이션 블록으로 래핑 하면 기본 애니메이션 대신 UIView 애니메이션이 사용되므로 다음과 같이 애니메이션 기간을 0으로 설정할 수 있습니다.
[UIView animateWithDuration:0 animations:^{
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:nil];
}];
삽입 및 삭제 중에 iOS 7 탄력있는 애니메이션을 사용하려는 경우 더욱 멋집니다!
performBatchUpdates
내부 포장 animateWithDuration
은 훌륭합니다! 팁 고마워!
UICollectionView는 reloadItemsAtIndexPaths가 호출 된 후 항목을 애니메이션합니다 (애니메이션 페이드).
이 애니메이션을 피할 수있는 방법이 있습니까?
iOS 6
FlowLayout을 사용하고 있다고 가정합니다. 페이드 애니메이션을 제거하려고하므로 다음을 시도하십시오.
import UIKit
class NoFadeFlowLayout: UICollectionViewFlowLayout {
override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attrs = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath)
attrs?.alpha = 1.0
return attrs
}
override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attrs = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath)
attrs?.alpha = 1.0
return attrs
}
}
이것은 매우 오래된 질문이므로 더 이상 iOS 6을 타겟팅하지 않을 것입니다. 나는 개인적으로 tvOS 11에서 작업하고 있었고 같은 질문이 있었기 때문에 이것은 같은 문제와 함께 오는 모든 사람들을 위해 여기에 있습니다.
내가 쓴 UICollectionView에 범주를 그냥 할 수 있습니다. 트릭은 다시로드하는 동안 모든 애니메이션을 비활성화하는 것입니다.
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
}
[self reloadItemsAtIndexPaths:indexPaths];
if (!animated) {
[CATransaction commit];
}
CATransaction.setDisableActions(true)
이것에 대한 속기처럼 할 수도 있습니다 .
extension UICollectionView {
func reloadWithoutAnimation(){
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
self.reloadData()
CATransaction.commit()
}
}
다음은 performBatchUpdates
애니메이션이없는 Swift 3 버전 UICollectionView
입니다. collectionView.reloadData()
레코드를 삽입 할 때 셀 스와핑을 줄 였기 때문에 이것이 나에게 더 잘 작동한다는 것을 알았습니다 .
func appendCollectionView(numberOfItems count: Int){
// calculate indexes for the items to be added
let firstIndex = dataItems.count - count
let lastIndex = dataItems.count - 1
var indexPaths = [IndexPath]()
for index in firstIndex...lastIndex {
let indexPath = IndexPath(item: index, section: 0)
indexPaths.append(indexPath)
}
UIView.performWithoutAnimation {
self.collectionView.performBatchUpdates({ () -> Void in
self.collectionView.insertItems(at: indexPaths)
}, completion: { (finished) -> Void in
})
}
}
- (void)reloadCollectionViewAnimated:(BOOL)animated {
if (animated) {
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
}];
} else {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
[CATransaction commit];
}
}
$ 0.02를 추가하기 위해 선택한 답변의 두 버전을 모두 시도했으며 원래 방법이 내 목적에 더 적합했습니다. 사용자가 주어진 주에 달력을 입력 한 다음 앞뒤로 스 와이프하고 목록을 필터링 할 개별 날짜를 선택할 수있는 무한 스크롤 달력보기를 작업 중입니다.
내 구현에서 오래된 장치에서 성능을 유지하려면 달력보기를 나타내는 날짜 배열을 상대적으로 작게 유지해야합니다. 즉, 사용자는 3 주 중간에 약 5 주 분량의 날짜를 유지해야합니다. 두 번째 접근 방식을 사용할 때의 문제는 애니메이션없이 컬렉션 뷰를 다시 가운데로 스크롤해야하는 두 번째 단계가 있으며, 이로 인해 차단 된 기본 애니메이션으로 인해 어떤 이유로 매우 들쭉날쭉 한 모양이됩니다.
내 코드 :
[UIView setAnimationsEnabled:NO];
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:indexPathDeleteArray];
[self.collectionView insertItemsAtIndexPaths:indexPathAddArray];
} completion:NULL];
[UIView setAnimationsEnabled:YES];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:14 inSection:0];
[self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
func reloadRowsWithoutAnimation(at indexPaths: [IndexPath]) {
let contentOffset = collectionView.contentOffset
UIView.setAnimationsEnabled(false)
collectionView.performBatchUpdates {
collectionView.reloadItems(at: indexPaths)
}
UIView.setAnimationsEnabled(true)
collectionView.setContentOffset(contentOffset, animated: false)
}