Пользовательская анимация для данных перезагрузки UICollectionView

Я хотел бы анимировать перезагрузку представления коллекции, чтобы при выборе ячейки я получал анимацию, похожую на раздачу карт в пасьянсе. (Изображение старой карты пасьянса 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;

Но это не дает моего желаемого эффекта. Любые идеи, как это можно сделать?


person Avner Barr    schedule 09.09.2013    source источник
comment
Для этого вам нужно создать подкласс UICollectionViewLayout. Нет другого варианта..   -  person itsji10dra    schedule 03.03.2015


Ответы (3)


Вы можете сделать какой-нибудь трюк, как предложено здесь

+ (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];
}

результат:

введите описание изображения здесь

person hbk    schedule 18.03.2016

Мне нравится ответ @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()
}
person Alex Bartiş    schedule 11.06.2017

Вам нужно создать пользовательскую UICollectionViewLayout, которая выполняет вашу пользовательскую анимацию. Если эффект представляет собой просто перевод из точки А в точку Б, вы можете обойтись довольно стандартным использованием встроенных анимаций. Вы должны установить местоположение ячейки в точку A в initialLayoutAttributesForAppearingItemAtIndexPath: и в точку B в layoutAttributesForItemAtIndexPath:. Если вы хотите раздать карты, вы просто вставите соответствующие индексные пути в представление коллекции с помощью performBatchUpdates:. Аналогичная анимация для отправки карт обратно дилеру должна использовать finalLayoutAttributesForDisappearingItemAtIndexPath:.

Если вы хотите сделать более сложную анимацию, у вас будет гораздо больше работы. Это, скорее всего, будет включать в себя снимок ячейки и ее преобразование перед анимацией по CGPath. Как только анимация будет завершена, вы должны указать представлению коллекции нарисовать ее в ее конечном месте.

person jszumski    schedule 20.04.2015