UIView animateWithDuration не изменяет параметр cornerRadius

Я пытаюсь оживить изменение cornerRadius UIView layer экземпляра UIView , но изменение 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; }]; 

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

РЕДАКТИРОВАТЬ:

Мне удалось оживить это свойство с помощью 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]; 

    tl; dr: Угловой радиус не анимативен в animateWithDuration:animations:


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

    Как говорится в разделе «Анимация» в «Руководстве по программированию для iOS»

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

    Полный список свойств , которые можно оживить, используя либо более старые

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

    или новее

     [UIView animateWithDuration:animations:]; 

    (которые вы используете):

    • Рамка
    • оценки
    • центр
    • transform (CGAffineTransform, а не CATransform3D)
    • альфа
    • фоновый цвет
    • contentStretch

    Как вы можете видеть, cornerRadius отсутствует в списке.

    Некоторая путаница

    Анимация UIView действительно предназначена только для анимации свойств вида. Что смущает людей, так это то, что вы также можете анимировать те же свойства на уровне внутри блока анимации UIView, то есть в рамке, границах, позиции, непрозрачности, backgroundColor. Поэтому люди видят анимацию слоев внутри animateWithDuration и считают, что они могут анимировать любое свойство вида.

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

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

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

    • Граница слоя (включая округление углов слоя)

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


    Некоторые дополнительные разъяснения

    Когда люди читают документацию, в которой говорится, что 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] в вашем classе вида. См. Этот вопрос для примера того, как.

    Начиная с iOS 10 вы действительно можете анималировать cornerRadius:

     UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) { square.layer.cornerRadius = 20 }.startAnimation() 
    Давайте будем гением компьютера.