【问题标题】:Custom animation on UICollectionView reload dataUICollectionView 上的自定义动画重新加载数据
【发布时间】: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。没有其他选择..

标签: ios uicollectionview uiviewanimation caanimation 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 制作动画之前对其进行转换。动画完成后,您将告诉集合视图将其绘制到最终位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 1970-01-01
        相关资源
        最近更新 更多