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];
Ответы
Ответ 1
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)
- alpha
- BackgroundColor
- contentStretch
Как вы можете видеть, cornerRadius
отсутствует в списке.
Некоторая путаница
анимации UIView действительно предназначены только для анимации свойств вида. Что смущает людей, так это то, что вы также можете анимировать те же свойства на слое внутри блока анимации UIView, то есть кадр, границы, положение, непрозрачность, backgroundColor. Поэтому люди видят анимацию слоев внутри animateWithDuration
и считают, что они могут анимировать любое свойство вида там.
В этом же разделе говорится:
В тех местах, где вы хотите выполнять более сложные анимации или анимации, не поддерживаемые классом UIView, вы можете использовать Core Animation и уровни, лежащие в основе, для создания анимации. Поскольку объекты вида и слоя сложно связаны друг с другом, изменения в уровне просмотров влияют на представление.
Несколько строк вниз вы можете прочитать список анимационных свойств Core Animation, где вы видите это:
- Граница слоев (включая округление углов слоев)
Итак, чтобы оживить cornerRadius
вам нужно использовать Core Animation, как вы уже сказали в своем обновленном вопросе (и ответе). Я просто добавил, что пытался объяснить, почему это так.
Дополнительные пояснения
Когда люди читают документацию, в которой говорится, что animateWithDuration
является рекомендуемым способом анимации, легко поверить, что он пытается заменить CABasicAnimation, CAAnimationGroup, CAKeyframeAnimation и т.д., но на самом деле это не так. Его заменяют beginAnimations:context:
и commitAnimations
, которые вы видели выше.
Ответ 2
Я использую это расширение для анимации изменения радиуса угла:
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
}
}
Ответ 3
Изменение углового радиуса может быть анимировано, но единственный способ сделать это - использовать CABasicAnimation. Надеюсь, это поможет кому-то там.
Ответ 4
Вы можете реализовать анимацию 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:"];
Ответ 5
Начиная с iOS 10 вы можете анимировать cornerRadius:
UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) {
square.layer.cornerRadius = 20
}.startAnimation()
Ответ 6
Не похоже, что это один из анимативных свойств.
См. полный список:
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html
Ответ 7
Вы можете сделать это свойство анимированным в +[UIView animateWithDuration:]
, реализовав -[actionForLayer:forKey]
в вашем классе вида. См. этот вопрос для примера того, как.
Ответ 8
Свойство CornerRadius является анимируемым
рабочий код ниже
//слой init
let imageLayer = CALayer()
imageLayer.frame = CGRect(x: 0, y: 0.0, width: tenPercent, height: tenPercent)
imageLayer.contents = imageNew.cgImage
imageLayer.masksToBounds = true
//анимация инициации
let animationCornerRadius = CABasicAnimation(keyPath: "cornerRadius")
animationCornerRadius.beginTime = 0.01
animationCornerRadius.duration = CFTimeInterval(5)
animationCornerRadius.fromValue = 1
animationCornerRadius.toValue = tenPercent / 2
animationCornerRadius.fillMode = .forwards
animationCornerRadius.isRemovedOnCompletion = false
imageLayer.add(animationCornerRadius , forKey: "cornerRadius")