68

我正在尝试为实例的变化设置动画cornerRadiusUIViewlayer变化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];
4

8 回答 8

90

tl; dr:圆角半径在animateWithDuration:animations:.


文档中有关视图动画的内容。

正如“View Programming Guide for iOS”中关于动画的部分所说

UIKit 和 Core Animation 都提供了对动画的支持,但是每种技术提供的支持程度各不相同。在 UIKit 中,动画是使用 UIView 对象执行的

您可以使用旧版本设置动画的完整属性列表

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

或更新的

[UIView animateWithDuration:animations:];

(您正在使用的)是:

  • 框架
  • 界限
  • 中央
  • 变换(CGAffineTransform,不是 CATransform3D)
  • α
  • 背景颜色
  • 内容拉伸

如您所见,cornerRadius不在列表中。

一些困惑

UIView 动画实际上仅用于动画视图属性。让人迷惑的是,你还可以在 UIView 动画块内部的图层上设置相同的属性,即 frame、bounds、position、opacity、backgroundColor。所以人们看到里面的图层动画,animateWithDuration并相信他们可以在那里为任何视图属性设置动画。

同一部分继续说:

在你想要执行更复杂的动画,或者 UIView 类不支持的动画的地方,你可以使用 Core Animation 和视图的底层来创建动画。因为视图和图层对象错综复杂地链接在一起,所以对视图图层的更改会影响视图本身。

几行之后,您可以阅读 Core Animation 可动画属性列表,您可以在其中看到:

  • 图层的边框(包括图层的角是否圆角)

因此,要制作动画,cornerRadius需要使用 Core Animation,正如您在更新的问题(和答案)中已经说过的那样。我刚刚添加试图解释为什么会这样。


一些额外的说明

当人们阅读说明这animateWithDuration是推荐的动画制作方式的文档时,很容易相信它正在尝试替换 CABasicAnimation、CAAnimationGroup、CAKeyframeAnimation 等,但实际上并非如此。它取代了你在上面看到的beginAnimations:context:and commitAnimations

于 2012-05-20T14:14:21.113 回答
25

我使用这个扩展来动画拐角半径的变化:

extension UIView
{
    func animateCornerRadius(from: CGFloat, to: CGFloat, duration: CFTimeInterval)
    {
        CATransaction.begin()
        let animation = CABasicAnimation(keyPath: "cornerRadius")
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        animation.fromValue = from
        animation.toValue = to
        animation.duration = duration
        CATransaction.setCompletionBlock { [weak self] in
            self?.layer.cornerRadius = to
        }
        layer.add(animation, forKey: "cornerRadius")
        CATransaction.commit()
    }
}
于 2016-01-17T19:10:35.830 回答
15

可以对角半径变化进行动画处理,但唯一的方法是使用 CABasicAnimation。希望这可以帮助那里的人。

于 2011-06-24T08:44:59.493 回答
13

您可以在此处实现 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:"];
于 2014-02-12T07:59:18.193 回答
12

iOS 10开始,您实际上可以为cornerRadius 设置动画:

UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) {
    square.layer.cornerRadius = 20
}.startAnimation()
于 2018-05-31T22:36:50.150 回答
2

看起来那不是动画属性之一。

完整列表请参见此处:

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

于 2011-05-11T01:57:29.837 回答
1

您可以通过在您的视图类中+[UIView animateWithDuration:]实现来使该属性具有动画效果。有关如何操作的示例,-[actionForLayer:forKey]请参阅此问题。

于 2012-06-05T17:49:52.177 回答
0

CornerRadius 属性是可动画的

工作代码如下

//层初始化

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")
于 2019-05-24T12:03:50.560 回答