我有一个用户界面,一个项目被删除,我想在iOS邮件中模仿“移动到文件夹”效果.将小字母图标“投入”到文件夹中的效果.我的矿将被丢弃在垃圾桶.
我尝试使用层上的CAAnimation实现它.就我可以在文档中读取,我应该能够设置一个byValue和一个toValue,CAAnimation应该内插值.我正在寻找一个小曲线,所以项目通过一点点在项目开始位置的一个上方和左边.
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"position"]; [animation setDuration:2.0f]; [animation setRemovedOnCompletion:NO]; [animation setFillMode:kCAFillModeForwards]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaSEOut]]; [animation setFromValue:[NSValue valueWithCGPoint:fromPoint]]; [animation setByValue:[NSValue valueWithCGPoint:byPoint]]; [animation setToValue:[NSValue valueWithCGPoint:CGPointMake(512.0f,800.0f)]]; [animation setRepeatCount:1.0];
我玩了一段时间,但在我看来,苹果意味着线性插值.
添加byValue不会计算出一个很好的弧线或曲线,并通过它激活该项目.
我该怎么做这样的动画?
感谢任何帮助.
解决方法
使用UIBezierPath
(不要忘记链接然后导入QuartzCore,如果您使用iOS 6或更早版本)
示例代码
您可以使用遵循路径的动画,方便的是,CAKeyframeAnimation支持CGPath,可从UIBezierPath获取. Swift 3
func animate(view : UIView,fromPoint start : CGPoint,toPoint end: CGPoint) { // The animation let animation = CAKeyframeAnimation(keyPath: "position") // Animation's path let path = UIBezierPath() // Move the "cursor" to the start path.move(to: start) // Calculate the control points let c1 = CGPoint(x: start.x + 64,y: start.y) let c2 = CGPoint(x: end.x,y: end.y - 128) // Draw a curve towards the end,using control points path.addCurve(to: end,controlPoint1: c1,controlPoint2: c2) // Use this path as the animation's path (casted to CGPath) animation.path = path.cgPath; // The other animations properties animation.fillMode = kCAFillModeForwards animation.isRemovedOnCompletion = false animation.duration = 1.0 animation.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseIn) // Apply it view.layer.add(animation,forKey:"trash") }
了解UIBezierPath
Bezier路径(或Bezier Curves,准确)的工作方式与Photoshop,烟火,草图中的相似.它们有两个“控制点”,每个顶点一个.例如,我刚刚做的动画:
像这样工作的贝塞尔路径.看到documentation on the specifics,但基本上是两个点,把弧向一个方向拉.
画一条路
关于UIBezierPath的一个很酷的功能是,您可以使用CAShapeLayer在屏幕上绘制它们,从而帮助您可视化其将遵循的路径.
// Drawing the path let *layer = CAShapeLayer() layer.path = path.cgPath layer.strokeColor = UIColor.black.cgColor layer.lineWidth = 1.0 layer.fillColor = nil self.view.layer.addSublayer(layer)
改进原来的例子
计算自己的bezier路径的想法是,你可以使完全动态,因此,动画可以改变它将要做的曲线,基于多个因素,而不是只是硬编码,就像我在示例中,为实例,控制点可以计算如下:
// Calculate the control points let factor : CGFloat = 0.5 let deltaX : CGFloat = end.x - start.x let deltaY : CGFloat = end.y - start.y let c1 = CGPoint(x: start.x + deltaX * factor,y: start.y) let c2 = CGPoint(x: end.x,y: end.y - deltaY * factor)
这最后一点的代码使得这些点与上一个数字一样,但是在一个可变的量中,相对于点形成的三角形乘以一个相当于“张力”值的因子.