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()