2010-12-27 10 views
10

Volevo animare un oggetto immagine spostandolo lungo una curva particolare. Non è una curva generale o casuale, ma piuttosto una curva che segue un particolare percorso sullo schermo.Spostamento di un oggetto lungo una curva nello sviluppo di iPhone

Attualmente, Im specifica manualmente l'elenco delle coordinate x e y del percorso lungo il quale voglio spostare l'oggetto immagine impostando la sua cornice ogni volta. Questo è un processo laborioso nel senso che sto impostando le specifiche coordinate xey del percorso e spostando l'immagine lungo di esso. C'è un modo più efficiente per farlo?

Esiste un modo per specificare, ad esempio, circa 15-20 punti e avere una curva tracciata lungo quelle per spostare l'oggetto? Qualche altro modo per raggiungere questo? Qualsiasi aiuto sarebbe molto apprezzato. Grazie.

risposta

10

È possibile utilizzare una combinazione di UIBezierPath e CAKeyFrameAnimation. Ho trovato un post del blog molto utile relativo a questo argomento.

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

Ecco una versione semplificata di quello che ho usato (solo anima il disegno di un quadrato):

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

Grazie. Questo ha aiutato. Invece di addLineToPoint io uso addQuadCurveToPoint e questo fa il lavoro. Un'altra domanda qui. Come posso rilevare la fine di una CAKeyFrameAnimation? C'è un metodo delegato per questo? Il delegato animationDidStop non è stato chiamato quando l'animazione si è interrotta. – Nathan

+0

Siamo spiacenti. Ho capito. Sciocco errore. Stavo usando il delegato animationDidStop di un UIView invece di quello per un CAAnimation. Ora anche il delegato lavora. – Nathan

0

In Swift-3 versione di @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

Problemi correlati