2016-09-12 1 views
1

J'utilise drawRect pour dessiner une forme assez simple (bleu foncé dans l'image ci-dessous). Je voudrais que cela anime de la gauche vers la droite, de sorte qu'il se développe. Le bémol ici est que j'ai besoin d'un fond "max" en gris, comme on le voit dans la partie supérieure de l'image.Utilisation de drawRect pour dessiner et animer deux graphiques. Un graphique d'arrière-plan et un graphique de premier plan

En ce moment, je simule cette animation en superposant une vue blanche, puis en animant sa taille, de sorte que le bleu semble s'animer vers la droite. Alors que cela fonctionne ... J'ai besoin de la forme grise de fond pour toujours être là. Avec ma vue blanche superposée, cela ne fonctionne tout simplement pas.

Voici le code pour dessiner le « code actuel » Version: partie

let context = UIGraphicsGetCurrentContext() 
    CGContextMoveToPoint(context, 0, self.bounds.height - 6) 
    CGContextAddLineToPoint(context, self.bounds.width, 0) 
    CGContextAddLineToPoint(context, self.bounds.width, self.bounds.height) 
    CGContextAddLineToPoint(context, 0, self.bounds.height) 
    CGContextSetFillColorWithColor(context,UIColor(red: 37/255, green: 88/255, blue: 120/255, alpha: 1.0).CGColor) 
    CGContextDrawPath(context, CGPathDrawingMode.Fill) 

Comment puis-je animer la partie bleue de gauche à droite, tout en gardant le « max » grise du graphique toujours visible?

Répondre

1

Pour obtenir l'animation que vous dites à propos, je vous recommande ce qui suit:

  1. Utilisez CoreAnimation pour produire l'animation
  2. Utilisez UIBezierPath pour faire une forme dont vous avez besoin
  3. Utilisez le masque de CALayer pour animer à l'intérieur de la forme requise

Voici un exemple de code pour Playground:

import UIKit 
import QuartzCore 
import XCPlayground 

let view = UIView(frame: CGRect(x: 0, y: 0, width: 120, height: 40)) 
XCPlaygroundPage.currentPage.liveView = view 

let maskPath = UIBezierPath() 

maskPath.moveToPoint(CGPoint(x: 10, y: 30)) 
maskPath.addLineToPoint(CGPoint(x: 10, y: 25)) 
maskPath.addLineToPoint(CGPoint(x: 100, y: 10)) 
maskPath.addLineToPoint(CGPoint(x: 100, y: 30)) 
maskPath.closePath() 

let maskLayer = CAShapeLayer() 
maskLayer.path = maskPath.CGPath 
maskLayer.fillColor = UIColor.whiteColor().CGColor 

let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 97, height: 40)) 
let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40)) 

let layerOne = CAShapeLayer() 
layerOne.path = maskPath.CGPath 
layerOne.fillColor = UIColor.grayColor().CGColor 

let layerTwo = CAShapeLayer() 
layerTwo.mask = maskLayer 
layerTwo.fillColor = UIColor.greenColor().CGColor 

view.layer.addSublayer(layerOne) 
view.layer.addSublayer(layerTwo) 

let animation = CABasicAnimation(keyPath: "path") 
animation.fromValue = rectToAnimateFrom.CGPath 
animation.toValue = rectToAnimateTo.CGPath 
animation.duration = 1 
animation.repeatCount = 1000 
animation.autoreverses = true 

layerTwo.addAnimation(animation, forKey: "Nice animation") 
+0

@SVGred - Wow, c'est génial! Pour l'essentiel, c'est exactement ce dont j'ai besoin! Je vais devoir le modifier un peu, mais c'est sur moi. Avec ma première implémentation du graphe, j'ai sous-classé UIView avec override func drawRect (rect: CGRect). N'aurai-je pas besoin de remplacer drawRect pour votre version? Aussi - pouvez-vous expliquer la toute dernière ligne? (layerTwo.addAnimation) J'ai également édité votre message à la syntaxe swift 2.3. Joue bien sur ma fin! – Joe

+0

@SVGreg avec plusieurs versions de Swift étant utilisé, il serait bon de mentionner que vous écrivez la réponse. – Dravidian

+1

@Joe: drawRect est requis uniquement pour dessiner du contenu personnalisé à l'intérieur de la vue. La réponse est - Non - vous n'avez pas besoin de surcharger * drawRect * pour utiliser mon code. addAnimation exécute réellement l'animation dont vous avez besoin.Vous pouvez le personnaliser à n'importe quelle animation que vous préférez. – SVGreg

0

Dans votre code, je ne vois que vous dessinez le graphique une fois, pourquoi ne pas dessiner d'abord la partie grise, puis dessiner la partie bleue.

Je ne pense pas qu'il soit assez efficace pour implémenter l'animation dans la fonction drawRect.

Vous pouvez jeter un oeil à Shimmer Example de Facebook, il simule l'effet de l'animation de déverrouillage iPhone. Il utilise une couche de masque. L'idée pourrait également fonctionner dans votre exemple.

En outre, le pop framework de Facebook pourrait simplifier votre travail. DrawRect produit une image fixe.

+0

« Dans votre code, je ne vois que vous dessinez le graphique une fois, pourquoi ne pas dessiner d'abord la partie grise puis dessiner la partie bleue. " - C'est le plan, tant que je trouve un moyen d'animer, ou peut-être d'animer le masque de la couche bleue. Merci pour les suggestions sur les frameworks, mais je veux garder tout cela natif sans tierces parties. – Joe