Анимация свойства shadowPath CALayer - PullRequest
9 голосов
/ 08 мая 2011

Мне известно, что shadowPath CALayer можно анимировать только с помощью явной анимации, однако я до сих пор не могу заставить это работать. Я подозреваю, что я не передаю toValue должным образом - насколько я понимаю, это должен быть id, но свойство принимает CGPathRef. Сохранение этого в UIBezierPath, похоже, не работает. Я использую следующий код для проверки:

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"];
theAnimation.duration = 3.0;
theAnimation.toValue = [UIBezierPath bezierPathWithRect:CGRectMake(-10.0, -10.0, 50.0, 50.0)];
[self.view.layer addAnimation:theAnimation forKey:@"animateShadowPath"];

(я использую минусовые значения, чтобы гарантировать, что тень выходит за пределы вида, который лежит поверх него ... Свойство слоя masksToBounds установлено на NO).

Как достигается анимация shadowPath?

UPDATE

Проблема почти решена. К сожалению, главной проблемой была несколько небрежная ошибка ...

Ошибка, которую я сделал, состояла в том, чтобы добавить анимацию к корневому слою контроллера представления, а не к слою, который я выделил для тени. Кроме того, @ pe8ter был прав в том, что toValue должен быть CGPathRef приведением к id (очевидно, когда я пробовал это раньше, у меня все еще не было анимации из-за неправильной ошибки слоя). Анимация работает со следующим кодом:

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"];
theAnimation.duration = 3.0;
theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:myRect].CGPath;
[controller.shadowLayer addAnimation:theAnimation forKey:@"shadowPath"];

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

Однако, когда я пытаюсь добавить строку

controller.shadowLayer.shadowPath = [UIBezierPath bezierPathWithRect:myRect].CGPath;

анимация перестает работать, и тень просто мгновенно переходит на конечную позицию. Документы говорят добавить анимацию с тем же ключом, что и изменяемое свойство, чтобы переопределить неявную анимацию, созданную при установке значения свойства, однако shadowPath не может генерировать неявные анимации ... так как я могу получить новое свойство остаться после анимации?

Ответы [ 2 ]

9 голосов
/ 08 мая 2011

Во-первых, вы не установили анимацию fromValue.

Во-вторых, вы правы: toValue принимает CGPathRef, за исключением того, что оно должно быть приведено к id.Сделайте что-то вроде этого:

theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:newRect].CGPath;

Вам также необходимо явно установить свойство shadowPath слоя, если вы хотите, чтобы изменение осталось после анимации.

1 голос
/ 06 августа 2015
let cornerRadious = 10.0
        //
        let shadowPathFrom = UIBezierPath(roundedRect: rect1, cornerRadius: cornerRadious)
        let shadowPathTo = UIBezierPath(roundedRect: rect2, cornerRadius: cornerRadious)
        //
        layer.masksToBounds = false
        layer.shadowColor = UIColor.yellowColor().CGColor
        layer.shadowOpacity = 0.6
        //
        let shadowAnimation = CABasicAnimation(keyPath: "shadowPath")
        shadowAnimation.fromValue = shadowPathFrom.CGPath
        shadowAnimation.toValue = shadowPathTo.CGPath
        shadowAnimation.duration = 0.4
        shadowAnimation.autoreverses = true
        shadowAnimation.removedOnCompletion = true
        shadowAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        layer.addAnimation(shadowAnimation, forKey: "shadowAnimation")
...