Można ustawić właściwość prędkości w warstwie (jak w [Odpowiedź Rotoavy]) (https://stackoverflow.com/a/23146861/5271393), aby zmienić kontrolę szybkości animacji. Problem polega na tym, że używasz arbitralnych wartości, ponieważ nie znasz faktycznego czasu trwania animacji wstawiania.
Za pomocą this post można ustalić, jaki jest domyślny czas trwania animacji.
newAnimationDuration = (1/layer.speed)*originalAnimationDuration
layer.speed = originalAnimationDuration/newAnimationDuration
Jeśli chcesz, aby długo 400ms animacja, w układzie byś:
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:indexPath];
//set attributes here
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
CGFloat originalAnimationDuration = [CATransaction animationDuration];
CGFloat newAnimationDuration = 0.4f;
cell.layer.speed = originalAnimationDuration/newAnimationDuration;
return attributes;
}
W moim przypadku miałem komórki, które mogą być przeciągane poza ekranem i chciałem zmienić czas trwania animacja usuwania w oparciu o szybkość gestu panoramy.
W rozpoznawania gestów (które powinny być częścią widoku kolekcji):
- (void)handlePanGesture:(UIPanGestureRecognizer *)sender
{
CGPoint dragVelocityVector = [sender velocityInView:self.collectionView];
CGFloat dragVelocity = sqrt(dragVelocityVector.x*dragVelocityVector.x + dragVelocityVector.y*dragVelocityVector.y);
switch (sender.state) {
...
case UIGestureRecognizerStateChanged:{
CustomLayoutClass *layout = (CustomLayoutClass *)self.collectionViewLayout;
layout.dragSpeed = fabs(dragVelocity);
...
}
...
}
Następnie w customLayout:
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:indexPath];
CGFloat animationDistance = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
CGFloat originalAnimationDuration = [CATransaction animationDuration];
CGFloat newAnimationDuration = animationDistance/self.dragSpeed;
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
cell.layer.speed = originalAnimationDuration/newAnimationDuration;
return attributes;
}
Według dokumentacji Apple: „Kiedy animowanie zmiany układu, czas animacji i parametry są kontrolowane przez widoku kolekcji”. Jest to w odniesieniu do metody setCollectionView: animated:, ale podejrzewam, że to samo dotyczy modyfikacji granic widoku kolekcji. Przepraszam, nie mogę pomóc, utknąłem na tym samym problemie. Podejrzewam, że odpowiedź leży gdzieś w samym obiekcie UICollectionView. – Ash