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 ответов:
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:"];
вы можете сделать это свойство анимируемым в
+[UIView animateWithDuration:]введя-[actionForLayer:forKey]в классе представления. Смотрите этот вопрос пример.
начиная с iOS 10 вы можете фактически анимировать cornerRadius:
UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) { square.layer.cornerRadius = 20 }.startAnimation()