CATransition Push переход с ранней заменой содержимого

У меня есть простая настройка анимации в приложении Mac, где элемент управления страницей меняет некоторые представления. Я очень близок к тому, чтобы получить анимацию, похожую на пейджинг, которую я хочу, но есть небольшая проблема. Разбиение по страницам работает, и новая страница анимируется правильно, но новая страница также заменяет исходную страницу до анимации. Я хочу, чтобы в конечном итоге представление, которое выталкивается, оставалось прежним, а не переходило на новую страницу раньше. Вот видео, показывающее проблему, длительность анимации замедлена до 3 секунд. Вот код:

UASourceView *previousSourceView = [self.sourceViewContainer.subviews objectAtIndex:0];
NSInteger previousIndex = [self.sourceViews indexOfObjectIdenticalTo:previousSourceView];

CATransition *pushTransition = [CATransition animation];
[pushTransition setType:kCATransitionPush];
[pushTransition setSubtype:(previousIndex < index) ? kCATransitionFromRight : kCATransitionFromLeft];
[pushTransition setDuration:PANEL_PAGE_SWIPE_ANIMATION_DURATION];
[pushTransition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[pushTransition setRemovedOnCompletion:YES];

[CATransaction begin];
[self.sourceViewContainer replaceSubview:previousSourceView with:sourceView];
[CATransaction commit];

[sourceView.layer addAnimation:pushTransition forKey:@"push"];

Существует фиксированное представление контейнера self.sourceViewContainer, которое заменяется новым подпредставлением при каждой анимации. Проблема, как показано выше, заключается в том, что previousSourceView немедленно заменяется на sourceView и также вставляется. Пожалуйста, помогите мне остановить немедленную замену. Где я ошибаюсь?

*Примечание: добавлен тег iOS, поскольку этот код не зависит от платформы.


person coneybeare    schedule 09.11.2012    source источник


Ответы (1)


Я решил похожие проблемы, используя CAAnimationBlocks (это мой форк original, автор которого двинулся в направлении, которое меня не особо заботило).

Идея состоит в том, чтобы установить removedOnCompletion на NO и fillMode на kCAFillModeForwards и выполнить фактическое переключение (без анимации) в блоке завершения. Это было протестировано только под OSX (вам может понадобиться другое решение для iOS, которое уже поддерживает блоки завершения).

Вот пример использования моего кода, который перемещает фигуру на шахматной доске и обратно:

CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.fromValue = [NSValue valueWithPoint:[self _pointForSquare:move.from()]];
moveAnimation.toValue = [NSValue valueWithPoint:[self _pointForSquare:move.to()]];
moveAnimation.duration = _animateSpeed / 1000.0;
moveAnimation.autoreverses = YES;
moveAnimation.removedOnCompletion = NO;
moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
moveAnimation.completion = ^(BOOL finished)
{
    [pieceLayer removeAnimationForKey:@"movePiece"];
    [self _setPieceLayer:pieceLayer toPiece:piece];
    [pieceLayer setNeedsDisplay];
};

[pieceLayer addAnimation:moveAnimation forKey:@"movePiece"];
person trojanfoe    schedule 09.11.2012