我有一个用户界面,项目被删除,我想模仿iOS邮件中的"移动到文件夹"效果.将小写字母图标"抛出"到文件夹中的效果.我的将被倾倒在垃圾箱中.
我尝试CAAnimation在图层上使用a 来实现它.据我所知,在文档中我应该能够设置a byValue和a 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];
Run Code Online (Sandbox Code Playgroud)
我玩了一段时间,但在我看来,Apple意味着线性插值.添加byValue不会计算出漂亮的弧或曲线,也无法通过它为项目设置动画.
我该怎么做这样的动画?
谢谢你给予的任何帮助.
Can*_*Can 31
(不要忘记链接然后import QuartzCore,如果您使用的是iOS 6或之前的版本)
你可以使用一个跟随路径的动画,足够方便,CAKeyframeAnimation支持a CGPath,可以从一个获得UIBezierPath.斯威夫特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")
}
Run Code Online (Sandbox Code Playgroud)
Bezier路径(或Bezier曲线,准确)的工作方式与您在photoshop,烟花,草图中找到的路径完全相同......它们有两个"控制点",每个顶点一个.例如,我刚刚制作的动画:

像这样工作bezier路径.请参阅有关细节的文档,但基本上是将两个点"拉"到某个方向的两个点.
一个很酷的功能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)
Run Code Online (Sandbox Code Playgroud)
计算你自己的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)
Run Code Online (Sandbox Code Playgroud)
最后一点代码使得这些点与上图相似,但是在可变量中,相对于点形成的三角形,乘以一个等于"张力"值的因子.
你是绝对正确的,用a动画位置CABasicAnimation使它成为一条直线.还有另一个类要求CAKeyframeAnimation进行更高级的动画.
values相反的toValue,fromValue和byValue基本的动画,你既可以使用数组values或一个完整的path,确定沿途的值.如果您想先将位置设置为侧面然后向下,则可以传递3个位置的数组(开始,中间,结束).
CGPoint startPoint = myView.layer.position;
CGPoint endPoint = CGPointMake(512.0f, 800.0f); // or any point
CGPoint midPoint = CGPointMake(endPoint.x, startPoint.y);
CAKeyframeAnimation *move = [CAKeyframeAnimation animationWithKeyPath:@"position"];
move.values = @[[NSValue valueWithCGPoint:startPoint],
[NSValue valueWithCGPoint:midPoint],
[NSValue valueWithCGPoint:endPoint]];
move.duration = 2.0f;
myView.layer.position = endPoint; // instead of removeOnCompletion
[myView.layer addAnimation:move forKey:@"move the view"];
Run Code Online (Sandbox Code Playgroud)
如果这样做,您会注意到视图从起点直线移动到中点,而在另一条直线上移动到终点.通过中点从头到尾缺少的部分是改变calculationMode动画.
move.calculationMode = kCAAnimationCubic;
Run Code Online (Sandbox Code Playgroud)
您可以通过改变控制它弧线tensionValues,continuityValues和biasValues性能.如果想要更精细的控制,可以定义自己的路径而不是values数组.
path要跟随您可以创建任何路径并指定该属性应遵循该路径.在这里,我使用一个简单的弧
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL,
startPoint.x, startPoint.y);
CGPathAddCurveToPoint(path, NULL,
controlPoint1.x, controlPoint1.y,
controlPoint2.x, controlPoint2.y,
endPoint.x, endPoint.y);
CAKeyframeAnimation *move = [CAKeyframeAnimation animationWithKeyPath:@"position"];
move.path = path;
move.duration = 2.0f;
myView.layer.position = endPoint; // instead of removeOnCompletion
[myView.layer addAnimation:move forKey:@"move the view"];
Run Code Online (Sandbox Code Playgroud)
我知道怎么做了。确实可以分别为 X 和 Y 制作动画。如果您在同一时间(低于 2.0 秒)对它们进行动画处理并设置不同的计时函数,则会使其看起来像是从开始值到结束值以弧线而不是直线移动。要调整弧度,您需要设置不同的计时函数。但不确定 CAAnimation 是否支持任何“性感”计时功能。
const CFTimeInterval DURATION = 2.0f;
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"position.y"];
[animation setDuration:DURATION];
[animation setRemovedOnCompletion:NO];
[animation setFillMode:kCAFillModeForwards];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[animation setFromValue:[NSNumber numberWithDouble:400.0]];
[animation setToValue:[NSNumber numberWithDouble:0.0]];
[animation setRepeatCount:1.0];
[animation setDelegate:self];
[myview.layer addAnimation:animation forKey:@"animatePositionY"];
animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
[animation setDuration:DURATION];
[animation setRemovedOnCompletion:NO];
[animation setFillMode:kCAFillModeForwards];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[animation setFromValue:[NSNumber numberWithDouble:300.0]];
[animation setToValue:[NSNumber numberWithDouble:0.0]];
[animation setRepeatCount:1.0];
[animation setDelegate:self];
[myview.layer addAnimation:animation forKey:@"animatePositionX"];
Run Code Online (Sandbox Code Playgroud)
编辑:
应该可以使用https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/CAMediaTimingFunction_class/Introduction/Introduction.html更改计时功能(CAMediaTimingFunction 由 functionWithControlPoints:::: 初始化)这是一个“三次贝塞尔曲线”。我确信谷歌那里有答案。http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves :-)
| 归档时间: |
|
| 查看次数: |
14481 次 |
| 最近记录: |