2016-05-29 4 views
0

Je crée une application de dessin. Au début, mon dessin est lisse. Quand je dessine une bande de cercles pendant une longue période, mon dessin commence à devenir énervé. Peut-être est-ce le fait qu'un tableau ne peut pas gérer trop de points?Pourquoi mon dessin est-il à la traîne après un long dessin?

DV.swift:

override func touchesBegan(touches: Set<UITouch>, withEvent  event: UIEvent?) { 
    lastPoint = touches.first!.locationInView(self) 

    self.setNeedsDisplay() 
} 
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    var newPoint = touches.first!.locationInView(self) 

    lines.append(Line(start: lastPoint, end: newPoint)) 

    lastPoint = newPoint 

    self.setNeedsDisplay() 

} 

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    var veryFirstPoint = touches.first!.locationInView(self) 
    lines.append(Line(start: lastPoint, end:veryFirstPoint)) 
    self.setNeedsDisplay() 
} 


override func drawRect(rect: CGRect) { 
    var context = UIGraphicsGetCurrentContext() 
    CGContextBeginPath(context) 

    for line in lines { 

     CGContextMoveToPoint(context,line.start.x , line.start.y) 
     CGContextAddLineToPoint(context, line.end.x, line.end.y) 


    } 
    CGContextSetRGBFillColor(context, 0, 0, 0, 1) 

    CGContextSetLineWidth(context, 5) 
    CGContextStrokePath(context) 
    } 

Exemple testé sur mon mini 4 iPad: Sur le côté gauche est le nombre déchiquetés après le dessin d'un tas de boucles. le côté droit est les premiers nombres que j'ai dessinés et ils sont lisses.

enter image description here

Répondre

0

Vous avez raison. Vous demandez au CPU de redessiner plusieurs chemins chaque fois que vous ajoutez une nouvelle "ligne", c'est-à-dire après chaque touche. Cela devient de plus en plus gourmand en processeur, plus vous avez de lignes. Une solution consiste à redessiner seulement les parties "sales" de votre vue. Vous pouvez le faire en utilisant setNeedsDisplayInRect(rect:CGRect) au lieu de setNeedsDisplay(). Par exemple, vous pouvez ajouter l'extension:

extension CGRect{ 
    static func rectWithTwoPoints(p1:CGPoint,p2:CGPoint) -> CGRect 
    { 
     return CGRectMake(min(p1.x, p2.x),min(p1.y, p2.y),fabs(p1.x - p2.x),fabs(p1.y - p2.y)); 
    } 
} 

Cela me donnera un rect englobant deux points quelconques. Maintenant, dans votre touchesMoved: et touchesEnded: nous pouvons appeler setNeedsDisplayInRect: comme ceci:

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let newPoint = touches.first!.locationInView(self) 

     lines.append(Line(start: lastPoint, end: newPoint)) 

     lastPoint = newPoint 

     self.setNeedsDisplayInRect(CGRectInset(CGRect.rectWithTwoPoints((lines.last?.start)!, p2: (lines.last?.end)!),-10.0,-10.0)) //would be better to not force unwrap and use magic numbers, but you get the idea 
    } 

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let veryFirstPoint = touches.first!.locationInView(self) 
     lines.append(Line(start: lastPoint, end:veryFirstPoint)) 
     self.setNeedsDisplayInRect(CGRectInset(CGRect.rectWithTwoPoints((lines.last?.start)!, p2: (lines.last?.end)!),-10.0,-10.0)) 
    } 

En utilisant CGRectInset pour développer notre rect un peu parce que nous avons un chemin largeur que si nous ne le redessiner rect retourné par rectWithTwoPoints prendrait en compte.

+0

Cela fonctionne! Le seul problème survient lorsque je dessine pendant un certain temps et que lorsque je commence à dessiner de nouvelles formes, il est en retard d'une seconde (seulement quand je pars de quelques points). Avez-vous une idée de ce que cela pourrait être? –

+0

Mise à jour: j'ai corrigé le problème. Tout ce que je faisais était copier et coller self.setNeedsDisplayInRect dans mes touchesBegan et remplacé les paramètres les deux premiers paramètres avec lastPoint. Merci beaucoup! –