2010-12-27 17 views
10

Quería animar un objeto de imagen moviéndolo a lo largo de una curva particular. No es una curva general o aleatoria, sino más bien una curva que sigue una ruta particular en la pantalla.Mover un objeto a lo largo de una curva en el desarrollo de iPhone

Actualmente, estoy especificando manualmente la lista de coordenadas xey de la ruta a lo largo de la cual quiero mover el objeto de la imagen estableciendo su marco cada vez. Este es un proceso laborioso en el sentido de que estoy configurando las coordenadas xey específicas de la ruta y moviendo la imagen a lo largo de ella. ¿Hay una manera más eficiente de hacer esto?

¿Hay alguna forma en que pueda especificar, digamos, entre 15 y 20 puntos y tener una curva trazada a lo largo de esas para mover el objeto? ¿Alguna otra forma de lograr esto? Cualquier ayuda sería muy apreciada. Gracias.

Respuesta

10

Puede usar una combinación de UIBezierPath y CAKeyFrameAnimation. Encontré una publicación de blog muy útil sobre este tema.

http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer/

Aquí hay una versión simplificada de lo que he utilizado (sólo anima el dibujo de un cuadrado):

UIBezierPath *customPath = [UIBezierPath bezierPath]; 
[customPath moveToPoint:CGPointMake(100,100)]; 
[customPath addLineToPoint:CGPointMake(200,100)]; 
[customPath addLineToPoint:CGPointMake(200,200)]; 
[customPath addLineToPoint:CGPointMake(100,200)]; 
[customPath addLineToPoint:CGPointMake(100,100)]; 

UIImage *movingImage = [UIImage imageNamed:@"foo.png"]; 
CALayer *movingLayer = [CALayer layer]; 
movingLayer.contents = (id)movingImage.CGImage; 
movingLayer.anchorPoint = CGPointZero; 
movingLayer.frame = CGRectMake(0.0f, 0.0f, movingImage.size.width, movingImage.size.height); 
[self.view.layer addSublayer:movingLayer]; 

CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 
pathAnimation.duration = 4.0f; 
pathAnimation.path = customPath.CGPath; 
pathAnimation.calculationMode = kCAAnimationLinear; 
[movingLayer addAnimation:pathAnimation forKey:@"movingAnimation"]; 
+0

Gracias. Eso ayudó. En lugar de addLineToPoint uso addQuadCurveToPoint y eso hace el trabajo. Otra pregunta aquí. ¿Cómo puedo detectar el final de una CAKeyFrameAnimation? ¿Hay algún método delegado para esto? El delegado animationDidStop no se llamó cuando la animación se detuvo. – Nathan

+0

Lo siento. Tengo eso arreglado. Error tonto. Estaba usando el delegado animationDidStop de un UIView en lugar del de una CAAnimation. Ahora el delegado también funciona. – Nathan

0

En la versión Swift-3 de @Jilouc: -

override func viewDidLoad() { 
     super.viewDidLoad() 
     addAdditiveAnimation() 
     initiateAnimation() 
    } 

    //curve which follows a particular path 
    func pathToTrace() -> UIBezierPath { 
      let path = UIBezierPath(ovalIn: CGRect(x: 120 , y: 120, width: 100, height: 100)) 
      let shapeLayer = CAShapeLayer() 
      shapeLayer.path = path.cgPath 
      shapeLayer.strokeColor = UIColor.red.cgColor 
      shapeLayer.lineWidth = 1.0 
      self.view.layer.addSublayer(shapeLayer) 
      return path 
     } 

func addAdditiveAnimation() { 
     let movement = CAKeyframeAnimation(keyPath: "position") 
     movement.path = pathToTrace().cgPath 
     movement.duration = 5 
     movement.repeatCount = HUGE 
     movement.calculationMode = kCAAnimationPaced 
     movement.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)] 
     self.movement = movement 
} 

func createLayer() -> CALayer { 
     let layer = CALayer() 
     let image = UIImage(named: "launch.png") 
     layer.frame = CGRect(x: 0 , y: 0, width: (image?.size.width),height: (image?.size.height)) 
     layer.position = CGPoint(x: 5, y: 5) 
     layer.contents = image?.cgImage 
     layer.anchorPoint = .zero 
     layer.backgroundColor = UIColor.red.cgColor 
     //layer.cornerRadius = 5 
     self.view.layer.addSublayer(layer) 
     return layer 
    } 

func initiateAnimation() { 
     let layer = createLayer() 
     layer.add(self.movement, forKey: "Object Movement") 
    } 

Github Demo

Cuestiones relacionadas