调用reloadItemsAtIndexPaths后的UICollectionView动画项(淡入淡出动画)。
有没有办法避免这个动画?
iOS 6
答案 0 :(得分:191)
值得注意的是,如果您定位iOS 7及更高版本,则可以使用新的UIView
方法performWithoutAnimation:
。我怀疑在幕后这与其他答案(暂时禁用UIView
动画/核心动画动作)的作用大致相同,但语法很干净。
特别是对于这个问题......
<强>目标-C:强>
[UIView performWithoutAnimation:^{
[self.collectionView reloadItemsAtIndexPaths:indexPaths];
}];
的夫特:强>
UIView.performWithoutAnimation {
self.collectionView.reloadItemsAtIndexPaths(indexPaths)
}
当然,这个原则可以应用于您希望确保更改 不 动画的任何情况。
答案 1 :(得分:150)
你也可以试试这个:
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弹性动画,这是非常酷的!
答案 2 :(得分:9)
调用reloadItemsAtIndexPaths后的UICollectionView动画项 (淡出动画)。
有没有办法避免这个动画?
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并且遇到了同样的问题,所以对于那些遇到同样问题的人来说,这就是问题所在。
答案 3 :(得分:7)
我写了category on UICollectionView来做到这一点。诀窍是在重新加载时禁用所有动画:
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
}
[self reloadItemsAtIndexPaths:indexPaths];
if (!animated) {
[CATransaction commit];
}
答案 4 :(得分:4)
以下是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
})
}
}
答案 5 :(得分:1)
- (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];
}
}
答案 6 :(得分:1)
只是加上我的0.02美元,我尝试了所选答案的两个版本,并且原始方式更适合我的目的。我正在开发一个无限滚动日历视图,允许用户在给定的一周输入日历,然后来回滑动并选择过滤列表的各个日期。
在我的实现中,为了保持旧设备的性能,表示日历视图的日期数组必须保持相对较小,这意味着保持约5周的日期,用户在第3个中间周。使用第二种方法的问题是,还有第二步,你必须在没有动画的情况下将集合视图滚动回中间,这会因为某些原因而使用基于阻塞的基本动画而出现锯齿状外观。
我的代码:
[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];
答案 7 :(得分:0)
extension UICollectionView {
func reloadWithoutAnimation(){
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
self.reloadData()
CATransaction.commit()
}
}
答案 8 :(得分:0)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="one" class="hide">one</p>
<p id="two" class="hide">two</p>
<button id="showOne">show one</button>
<button id="showTwo">show two</button>
答案 9 :(得分:0)
不要使用 reloadData()
尝试以下重新加载所有可见单元格而没有动画。
self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)