UICollectionView 上的自定义动画重新加载数据
Posted
技术标签:
【中文标题】UICollectionView 上的自定义动画重新加载数据【英文标题】:Custom animation on UICollectionView reload data 【发布时间】:2013-09-09 20:59:30 【问题描述】:I would like to animate the reload of a collection view such that when a cell is selected I get an animation similar to dealing cards in a solitaire game. (想象旧的 MS 纸牌)
我搜索了“自定义 UICollectionView 重新加载动画”并看到了诸如
之类的解决方案[self.collectionView performBatchUpdates:^
[self.collectionView reloadItemsAtIndexPaths:myindexPaths]
completion:nil];
并想出了这个
CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
[self.collectionView.layer addAnimation:transition forKey:nil];
[self.collectionView reloadData];
return;
但这并没有达到我想要的效果。 有什么想法可以做到吗?
【问题讨论】:
为了实现这一点,您必须继承UICollectionViewLayout
。没有其他选择..
【参考方案1】:
你可以像建议的here那样做一些技巧
+ (CATransition *)swipeTransitionToLeftSide:(BOOL)leftSide
CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = leftSide ? kCATransitionFromRight : kCATransitionFromLeft;
transition.duration = AnimationDuration;
return transition;
并将其添加到您的collectionView
UISwipeGestureRecognizer *swipeGestureL = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipeToLeftCollectionView:)];
swipeGestureL.direction = UISwipeGestureRecognizerDirectionLeft;
[self.collectionView addGestureRecognizer:swipeGestureL];
- (void)didSwipeToLeftCollectionView:(UISwipeGestureRecognizer *)swipeGesture
[self.collectionView.layer addAnimation:[Animation swipeTransitionToLeftSide:YES] forKey:nil];
[self.collectionView reloadData];
结果:
【讨论】:
【参考方案2】:我喜欢@gbk 的回答,所以它在 Swift 3.1 中适用于左右
override func viewDidLoad()
super.viewDidLoad()
let swipeGestureL = UISwipeGestureRecognizer(target: self, action: #selector(swipeLeft))
swipeGestureL.direction = .left
collectionView.addGestureRecognizer(swipeGestureL)
let swipeGestureR = UISwipeGestureRecognizer(target: self, action: #selector(swipeRight))
swipeGestureR.direction = .right
collectionView.addGestureRecognizer(swipeGestureR)
func swipeTransitionToLeftSide(_ leftSide: Bool) -> CATransition
let transition = CATransition()
transition.startProgress = 0.0
transition.endProgress = 1.0
transition.type = kCATransitionPush
transition.subtype = leftSide ? kCATransitionFromRight : kCATransitionFromLeft
transition.duration = 0.3
return transition
@IBAction func swipeLeft()
collectionView.layer.add(swipeTransitionToLeftSide(true), forKey: nil)
updateDasource()
@IBAction func swipeRight()
collectionView.layer.add(swipeTransitionToLeftSide(false), forKey: nil)
updateDatasource()
func updateDatasource()
self.collectionView.reloadData()
【讨论】:
【参考方案3】:您需要创建一个自定义 UICollectionViewLayout
来执行您的自定义动画。如果效果只是从 A 点到 B 点的平移,您可以通过非常标准地使用内置动画来使用 getaway。您可以将单元格的位置设置为initialLayoutAttributesForAppearingItemAtIndexPath:
中的A 点和layoutAttributesForItemAtIndexPath:
中的B 点。当你想发牌时,你只需将相应的索引路径插入到集合视图中,performBatchUpdates:
。将牌发回给庄家的类似动画应使用finalLayoutAttributesForDisappearingItemAtIndexPath:
。
如果您想制作更复杂的动画,您将需要做更多的工作。这很可能包括对单元格进行快照并在沿CGPath
制作动画之前对其进行转换。动画完成后,您将告诉集合视图将其绘制到最终位置。
【讨论】:
以上是关于UICollectionView 上的自定义动画重新加载数据的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 或 UICollectionView 中的自定义滚动行为
UICollectionView:使用动画和自定义布局调整单元格大小
iOS - 未应用我的 UICollectionViewCell 上的自定义