2015-04-29 1 views
0

Je crée une application qui simule une accélération du moteur. Quand je glisse un UISlider, je veux que le pointeur de jauge RPM augmente et que UILabel dans le RPM soit mis à jour. J'ai tout fonctionné à l'exception d'une partie bizarre: le texte dans UILabel écrase lui-même (c'est-à-dire qu'il se dessine sur lui-même de sorte que toutes les valeurs se superposent et qu'il soit illisible). Voici le code de curseur dans mon ViewController:Comportement bizarre rapide lorsque setNeedsDisplay est appelé

@IBAction func changeThrottleSetting(sender: UISlider) 
{ 
    compactEngineView.RPMPointerAngleInt = Int(sender.value) 
    compactEngineView.setNeedsDisplay() 
} 

Ensuite, dans le compactEngineView lui-même:

var RPMPointerAngleInt = Int() 

var RPMPointerAngle: CGFloat { //this angle is used to draw the pointer points later down in the code, didn't show it here just to keep it shorter 
    var AngleCGFloat = CGFloat(RPMPointerAngleInt) 
    var Pi = CGFloat(M_PI) 
    var CorrectedAngle = (9 * Pi/800) * AngleCGFloat - (Pi/2) //just some math to make it look right on the display 
    return CorrectedAngle 
} 

var RPMPercentageValue: Int { 
    var correctedValue = (0.55) * Float(RPMPointerAngleInt) + 55 
    return Int(correctedValue) 
} 

override func drawRect(rect: CGRect) 
{ 
    let RPMPointerPath = UIBezierPath() 
    RPMPointerPath.moveToPoint(RPMPointer1) 
    RPMPointerPath.addLineToPoint(RPMPointer2) 
    RPMPointerPath.addLineToPoint(RPMPointer3) 
    RPMPointerPath.addLineToPoint(RPMPointer1) 
    whiteColor.set() 
    RPMPointerPath.stroke() 
    RPMPointerPath.fill() 

    //here is the troublemaker 
    let RPMdisplaylabel = UILabel(frame: CGRectMake(0, 0, 81, 32)) 
    RPMdisplaylabel.center = RPMdisplayLocation 
    RPMdisplaylabel.textAlignment = NSTextAlignment.Right 
    RPMdisplaylabel.text = "\(RPMPercentageValue)%" 
    RPMdisplaylabel.textColor = UIColor.whiteColor() 
    RPMdisplaylabel.font = UIFont(name: "HelveticaNeue", 
     size: 27.0) 
    self.addSubview(RPMdisplaylabel) 
} 

Le pointeur fonctionne parfaitement. Aucune plainte. Mais le texte se dessine juste à chaque fois que je déplace le curseur. Y a-t-il une astuce distincte pour UILabels dans la partie DrawRect? Merci!

Répondre

1
//here is the troublemaker 
let RPMdisplaylabel = UILabel(frame: CGRectMake(0, 0, 81, 32)) 
RPMdisplaylabel.center = RPMdisplayLocation 
RPMdisplaylabel.textAlignment = NSTextAlignment.Right 
RPMdisplaylabel.text = "\(RPMPercentageValue)%" 
RPMdisplaylabel.textColor = UIColor.whiteColor() 
RPMdisplaylabel.font = UIFont(name: "HelveticaNeue", 
    size: 27.0) 
self.addSubview(RPMdisplaylabel) 

Vous faites quelque chose que vous ne devriez jamais faire: dans drawRect:, vous faites quelque chose de plus que le dessin à l'intérieur du rect! Le travail de drawRect: est de dessiner le contenu à l'intérieur du rect et pas plus ou moins. C'est pas l'endroit pour ajouter des sous-vues! Et vous avez découvert une raison pour laquelle: depuis drawRect: peut être appelé des milliers de fois au cours de la durée de vie de l'application, vous finirez par ajouter des milliers de sous-vues identiques.

Donc, ce qui se passe ici, c'est que vous créez et ajoutez un UILabel, encore et encore et encore et encore ... Donc vous vous retrouvez avec des gazillions de UILabels, tous au même endroit et se chevauchant ainsi résultat que vous avez correctement décrit. Solution: ajouter l'étiquette une fois, ailleurs.. Ne pas abuser drawRect: pour cela.

+0

Merci @matt. J'ai essayé de le déplacer en dehors du 'DrawRect' dans le code UIView, mais quand je le fais, j'obtiens une erreur la première fois que j'essaie de dire' RPMdisplaylabel.center': "Déclaration attendue." – sparrownova

+0

J'ai également essayé de déplacer le tout dans le ViewController mais j'ai le même problème que le problème d'origine avec le texte écrit sur lui-même. – sparrownova

+0

Pouvez-vous offrir une suggestion sur où et comment le déplacer? – sparrownova