UIView animateWithDuration не анимирует изменение cornerRadius


Я пытаюсь оживить изменение cornerRadius на UIView экземпляр layer, но вариации cornerRadius происходит сразу.

вот код:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
view.layer.masksToBounds = YES;
view.layer.cornerRadius = 10.0;
[UIView animateWithDuration:1.0 animations:^{

    [view.layer.cornerRadius = 0.0;

}];

спасибо всем, кто собирается дать мне какие-либо советы.

EDIT:

мне удалось оживить это свойство с помощью Core Animation, С помощью CABasicAnimation.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:10.0f];
animation.toValue = [NSNumber numberWithFloat:0.0f];
animation.duration = 1.0;
[viewToAnimate.layer addAnimation:animation forKey:@"cornerRadius"];
[animation.layer setCornerRadius:0.0];
7 55

7 ответов:

tl; dr: радиус угла не анимируется в animateWithDuration:animations:.


что говорится в документации о просмотре анимации.

как раздел по анимации в" View Programming Guide for iOS " написано

как UIKit, так и Core Animation обеспечивают поддержку анимации, но уровень поддержки, предоставляемой каждой технологией, варьируется. В UIKit анимация выполняется с помощью UIView объекты

The полный список свойств что вы можете анимировать с помощью либо старше

[UIView beginAnimations:context:];
[UIView setAnimationDuration:];
// Change properties here...
[UIView commitAnimations];

или новее

[UIView animateWithDuration:animations:];

(что вы используете) являются:

  • рама
  • границы
  • центр
  • transform (CGAffineTransform, а не CATransform3D)
  • Альфа
  • backgroundColor
  • contentStretch

Как видите, cornerRadius нет в списке.

путаница

анимация UIView действительно предназначена только для анимации свойств представления. Людей смущает то, что вы также можете анимировать одни и те же свойства на слое внутри блока анимации UIView, т. е. кадр, границы, положение, непрозрачность, цвет фона. Так что люди видят слой анимации внутри animateWithDuration и поверьте, что они могут анимировать любое свойство представления там.

в том же разделе говорится:

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

несколько строк вниз вы можете прочитать список основных анимационных анимируемых свойств, где вы видите это:

  • граница слоя (в том числе закруглены ли углы слоя)

Итак, чтобы оживить cornerRadius вы нужно чтобы использовать основную анимацию, как вы уже сказали в своем обновленном вопросе (и ответе). Я просто добавил попытался объяснить, почему это так.


дополнительные пояснения

когда люди читают документы, в которых говорится, что animateWithDuration рекомендуемый способ анимации легко поверить, что он пытается заменить CABasicAnimation, CAAnimationGroup, CAKeyframeAnimation и т. д. но это действительно не так. Его замена beginAnimations:context: и commitAnimations что вы видели выше.

Я использую это расширение для анимации изменения радиуса угла:

extension UIView
{
    func addCornerRadiusAnimation(from: CGFloat, to: CGFloat, duration: CFTimeInterval)
    {
        let animation = CABasicAnimation(keyPath:"cornerRadius")
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        animation.fromValue = from
        animation.toValue = to
        animation.duration = duration
        layer.add(animation, forKey: "cornerRadius")
        layer.cornerRadius = to
    }
}

изменение радиуса угла может быть анимировано, но единственный способ сделать это-использовать CABasicAnimation. Надеюсь, это поможет кому-то там.

вы можете реализовать анимацию UIView, как здесь: http://maniacdev.com/2013/02/ios-uiview-category-allowing-you-to-set-up-customizable-animation-properties

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
animation.duration = DURATION;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.toValue = @(NEW_CORNER_RADIUS);
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
[view.layer addAnimation:animation forKey:@"setCornerRadius:"];

не похоже, что это одно из свойств анимируются.

смотрите здесь полный список:

http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

вы можете сделать это свойство анимируемым в +[UIView animateWithDuration:] введя -[actionForLayer:forKey] в классе представления. Смотрите этот вопрос пример.

начиная с iOS 10 вы можете фактически анимировать cornerRadius:

UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) {
    square.layer.cornerRadius = 20
}.startAnimation()