我遇到了一个我似乎无法弄清楚的问题。在我的应用程序中,我使用自定义UIImageView类来表示可移动对象。有些是使用静态.png图像加载并使用帧动画,而有些是从.svg文件加载CAShapeLayer路径。对于其中一些,当图层从一个路径动画到另一个路径时,我会变得口吃,而UIImageView正在移动。
您可以在关联的视频中看到它。当我触摸美人鱼号角时,一个音符会产生(svg路径)并动画成鱼(另一条svg路径),同时向上漂移。在动画/漂移期间发生口吃。这是我第三次产生鱼类时最引人注目的,大约19秒进入视频。 (每个动画结束时我需要单独修复,所以不要担心)
http://www.youtube.com/watch?v=lnrNWuvqQ4w
当我在iOS模拟器中测试应用程序时,这不会发生 - 一切都很顺利。在我的iPad 2上它口吃。当我关闭音符/鱼的运动(向上漂移)时,它在iPad上平滑动画,所以很明显它与移动视图同时进行。有一些我想念的东西,但我无法弄清楚。
以下是我设置动画的方法。 PocketSVG是我在Github上找到的一个类,它将.svg转换为Bezier路径。
animShape = [CAShapeLayer layer];
[animShape setShouldRasterize:YES];
[animShape setRasterizationScale:[[UIScreen mainScreen] scale]];
PocketSVG *tSVG;
UIBezierPath *tBezier;
PocketSVG *tSVG2;
UIBezierPath *tBezier2;
CAShapeLayer *tLayer2;
CABasicAnimation *animBezier;
CABasicAnimation *animScale;
tSVG = [[PocketSVG alloc] initFromSVGFileNamed:[NSString stringWithFormat:@"%@", tName]];
// Use PocketSVG to convert the SVG to a Bezier Path
tBezier = tSVG.bezier;
animShape.path = tBezier.CGPath;
animShape.lineWidth = 1;
animShape.strokeColor = [[UIColor blackColor] CGColor];
animShape.fillColor = [[UIColor blackColor] CGColor];
animShape.fillRule = kCAFillRuleNonZero;
// Set the frame & bounds to position the piece and set anchor point for rotation
// parentPaper is the Mermaid the note spawns from
CGPoint newCenter;
CGFloat imageScale = fabsf(parentPaper.transform.a);
newCenter = // Code excised, set center based on custom spawn points in relation to parent position and scale
animShape.bounds = CGPathGetBoundingBox(animShape.path);
CGRect lBounds = CGRectMake(newCenter.x, newCenter.y, animShape.bounds.size.width, animShape.bounds.size.height);
[animShape setFrame:lBounds];
halfSize = CGPointMake(animShape.bounds.size.width/2, animShape.bounds.size.height/2);
animShape.anchorPoint = CGPointMake(prp.childSpawnX, prp.childSpawnY);
// Create the end path for animation
tSVG2 = [[PocketSVG alloc] initFromSVGFileNamed:[NSString stringWithFormat:@"%@2", tName]];
tBezier2 = tSVG2.bezier;
tLayer2 = [CAShapeLayer layer];
tLayer2.path = tBezier2.CGPath;
// Create the animation and add it to the layer
animBezier = [CABasicAnimation animationWithKeyPath:@"path"];
animBezier.delegate = self;
animBezier.duration = prp.frameDur;
animBezier.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animBezier.fillMode = kCAFillModeForwards;
animBezier.removedOnCompletion = NO;
animBezier.autoreverses = behavior.autoReverse;
if (prp.animID < 0) {
animBezier.repeatCount = FLT_MAX;
}
else {
animBezier.repeatCount = prp.animID;
}
animBezier.fromValue = (id)animShape.path;
animBezier.toValue = (id)tLayer2.path;
[animShape addAnimation:animBezier forKey:@"animatePath"];
// also scale the animation if spawned from a parent
// i.e. small note to normal-sized fish
if (parentPaper != nil) {
animScale = [CABasicAnimation animationWithKeyPath:@"transform"];
animScale.delegate = self;
animScale.duration = prp.frameDur;
animScale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animScale.fillMode = kCAFillModeForwards;
animScale.removedOnCompletion = YES;
animScale.autoreverses = NO;
animScale.repeatCount = 1;
animScale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(imageScale, imageScale, 0.0)];
animScale.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 0.0)];
[animShape addAnimation:animScale forKey:@"animateScale"];
}
[self.layer addSublayer:animShape];
这基本上就是我如何移动UIImageView。我使用60帧的CADisplayLink,根据animShape.position
的现有位置找出新的位置,并像这样更新,其中self
是UIImageView:
[self.animShape setPosition:paperCenter];
其他一切运行顺畅,就是这一组物体在iPad上运行时会出现断断续续的跳跃。我做错了什么想法?也许是以错误的方式移动它?我仍然对图层,边框和边界感到困惑。
答案 0 :(得分:0)
为了解决这个问题,我最终改变了UIImageView的移动方式。我没有通过游戏循环改变帧位置,而是将其切换到位置上的CAKeyframeAnimation,因为它只是一次运行的临时运动。我用CGPathAddCurveToPoint
复制了我原来的正弦波运动。这很简单,我可能应该以这种方式开始。
我只能猜测,口吃是由于它在动画中分别通过CADisplayLink循环移动。