Ios UIView animateWithDuration不';设置拐角半径变化的动画

Ios UIView animateWithDuration不';设置拐角半径变化的动画,ios,uiview,core-animation,uiviewanimation,cornerradius,Ios,Uiview,Core Animation,Uiviewanimation,Cornerradius,我正在尝试设置UIView实例层的cornerRadius更改的动画,但是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:^{

我正在尝试设置
UIView
实例
层的
cornerRadius
更改的动画,但是
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];

看起来这不是可设置动画的属性之一

有关完整列表,请参见此处:


可以设置角半径变化的动画,但唯一的方法是使用CABASICANIATION。希望这有助于其他人。

tl;dr:角半径在
动画中不可设置动画,持续时间:动画:


文档中关于视图动画的说明。 正如“iOS查看编程指南”中的

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

属性的完整列表,您可以使用较旧的

[UIView beginAnimations:context:];
[UIView setAnimationDuration:];
// Change properties here...
[UIView commitAnimations];
还是更新的

[UIView animateWithDuration:animations:];
(您正在使用的)是:

  • 框架
  • 界限
  • 居中
  • 转换(CGAffineTransform,而不是CATTransform3D)
  • 阿尔法
  • 背景色
  • 内容延伸
如您所见,
cornerRadius
不在列表中

有些混乱 UIView动画实际上仅用于设置视图属性的动画。令人困惑的是,您还可以在UIView动画块内的层上设置相同属性的动画,即帧、边界、位置、不透明度、背景色。所以人们在
animateWithDuration
中看到层动画,并相信他们可以在其中设置任何视图属性的动画

同一节接着说:

在希望执行更复杂动画或UIView类不支持的动画的位置,可以使用核心动画和视图的底层来创建动画。由于视图和图层对象错综复杂地链接在一起,因此对视图图层的更改会影响视图本身

在下面几行中,您可以阅读核心动画可设置动画的属性列表,其中您可以看到以下内容:

  • 层的边界(包括层的角是否为圆角)
因此,要制作
corneradius
的动画,您需要使用核心动画,正如您在更新的问题(和答案)中所说的那样。我只是想解释一下为什么会这样


一些额外的澄清
当人们阅读文档时,认为
animateWithDuration
是推荐的动画制作方式,很容易让人相信它正在试图取代CABasicAnimation、CAAnimationGroup、CAKeyframeAnimation等,但事实并非如此。它取代了上面看到的
beginAnimations:context:
commitAnimations

通过在视图类中实现
-[actionForLayer:forKey]
,可以在
+[UIView animateWithDuration:][uicode>中设置此属性的动画。有关如何实现UIView动画的示例,请参见。

您可以在此处实现UIView动画:

cabasicanition*动画=[cabasicanition animationWithKeyPath:@“拐角半径”];
animation.duration=持续时间;
animation.timingFunction=[CamediaTimingFunctionWithName:kCAMediaTimingFunctionLinear];
animation.toValue=@(新的角点半径);
animation.fillMode=kCAFillModeForwards;
animation.removedOnCompletion=否;
[view.layer addAnimation:animation-forKey:@“setCornerRadius:”;

我使用此扩展来设置角半径更改的动画:

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()
    }
}
从中开始,您可以实际设置拐角半径的动画:

UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) {
    square.layer.cornerRadius = 20
}.startAnimation()

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

好。。。如果您使用旧的动画方法,它将工作。。。但是如果你尝试使用苹果公司建议的方法,它就不会产生动画效果。@singingatomanimatewithduration:和CABasicAnimations实际上不是一回事,所以没有新的或旧的方法。animateWithDuration不是核心动画的一部分,只能为视图属性设置动画(cornerRadius是层属性)。animateWithDuration所取代的真正的旧方法是[UIView beginAnimations:context:]和[UIView commitAnimation],其工作方式与新方法完全相同。Apple建议使用animateWithDuration:作为视图属性,并继续说,对于更高级的动画,您应该使用核心动画。尝试此方法,使您的动画坚持新的值:
Animation.removedOnCompletion=NO
animation.fillMode=kCAFillModeForwards@MohammadAbdurraafay不,请不要。这是制作动画“粘住”的错误方法。@DavidRönnqvist为什么不
animation.removedOnCompletion=NO可以使用吗?您在此处或回答中都没有给出其他建议。@DavidRönnqvist链接没有附加。@user1763532让我们再试一次:解释了
removeOnCompletion=no
的一些问题,并给出了一个替代解决方案。回答不错。指出所有文档的道具。完美答案。帮助很大。非常感谢。这在iOS 11中发生了变化,请参考我的回答,效果非常好。您不需要from字段,因为它应该始终是
层。cornerRadius
。谢谢,它在我的UIView.animate块中工作得很好,即将UIView的移动与其cornerRadius的更改相结合。从iOS 11开始,它是可设置动画的,因为iOS 11 cornerRadius是可设置动画的属性。iOS 10+提供了它。