Реализация толчка CATransition с помощью CAAnimation

Как вы реализуете kCATransitionPush с помощью CAAnimation подклассы в iOS?

CAAnimation *animation;
// How do you create an animation that does the same than:
// CATransition *animation = [CATransition animation];
// [animation setType:kCATransitionPush];        
[self.view.layer addAnimation:animation forKey:nil];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];        
[self.view addSubview:change];
[UIView commitAnimations];

Я знаю что UIView анимации также можно использовать, но это помогло бы мне лучше понять Core Animation, если бы я мог реализовать kCATransitionPush переход с нуля.

2 ответа

Решение

Чтобы одновременно выполнять анимацию над двумя слоями, необходимо добавить адекватную CAAnimationGroup к каждому слою.

[nextView.layer addAnimation:nextViewAnimation forKey:nil];
[currentView.layer addAnimation:currentViewAnimation forKey:nil];

nextViewAnimation будет:

CAAnimationGroup *nextViewAnimation = [CAAnimationGroup animation];
NSMutableArray *nextAnimations = [NSMutableArray array];

[nextAnimations addObject:[self opacityAnimation:YES]];  // fade in

CGPoint fromPoint = CGPointMake(forward ? nextView.center.x + nextView.frame.size.width : nextView.center.x - nextView.frame.size.width, nextView.center.y);
[nextAnimations addObject:[self positionAnimationFromPoint:fromPoint toPoint:nextView.center]];  // traslation in

nextViewAnimation.animations = nextAnimations;

и currentViewAnimation:

CAAnimationGroup *currentViewAnimation = [CAAnimationGroup animation];
NSMutableArray *currentAnimations = [NSMutableArray array];
[currentSceneAnimations addObject:[self opacityAnimation:NO]]; // fade out

CGPoint toPoint = CGPointMake(forward ? currentView.center.x - currentView.frame.size.width : currentView.center.x + currentView.frame.size.width, currentView.center.y);
    [currentAnimations addObject:[self positionAnimationFromPoint:currentView.center toPoint:toPoint]];  // traslation out

currentViewAnimation.animations = currentAnimations;

Эти методы создают основные анимации:

- (CABasicAnimation *)opacityAnimation:(BOOL)fadeIn {
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"opacity"];
a.fromValue = [NSNumber numberWithFloat:fadeIn ? 0.0 : 1.0];
a.toValue = [NSNumber numberWithFloat:fadeIn ? 1.0 : 0.0];
return a;
}

- (CABasicAnimation *)positionAnimationFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"position"];
a.fromValue = [NSValue valueWithCGPoint:fromPoint];
a.toValue = [NSValue valueWithCGPoint:toPoint];
return a;
}

С помощью логического значения вперед вы можете смоделировать переход "слева" или "справа".

По умолчанию kCATransitionPush действительно включает исчезновение. Чтобы повторить переход, используя свой собственный CABasicAnimation Сначала вам нужно понять, как работает анимация. Я делаю это без тестирования, так что это может быть отключено, но если я правильно помню, анимация, где подслой B заменяет подслой A, работает следующим образом:

  • Слой А перемещается из исходного положения вправо
  • Слой B перемещается справа в исходное положение A
  • Первая половина слоя анимации B анимирует свою непрозрачность от 0 до 1
  • Вторая половина слоя анимации А анимирует свою непрозрачность от 1 до 0 (конечно, вы можете заменить вправо в любом направлении здесь).

CABasicAnimation поддерживает анимацию только одного свойства, поэтому вам придется создать CAAnimationGroup который управляет 4 различными анимациями.

Создайте анимацию для положения и непрозрачности следующим образом:

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.fromValue = [NSValue valueWithCGPoint:startPoint];
anim.toValue = [NSValue valueWithCGPoint:endPoint];

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
anim.fromValue = [NSNumber numberWithFloat:0.0];
anim.toValue = [NSNumber numberWithFloat:1.0];
Другие вопросы по тегам