Dessin de lignes courbes sans retard?

J'ai une class ci-dessous qui, lorsqu'elle est attachée à une vue dessine des lignes courbes lorsque l'user touche leur appareil. Le problème est que les lignes tracées semblent être en retard par rapport à la position du doigt sur l'écran. Le retard est suffisant pour être perceptible et légèrement ennuyeux car de nouvelles sections de la ligne s'affichent à une petite distance du doigt touchant l'écran.

Le code utilise la méthode de courbe addCurveToPoint . (La méthode de courbe addQuadCurveToPoint alternative semble être less supérieure en termes de ligne courbe de qualité, mais s'affiche plus rapidement à l'écran.)

Je suspecte que ce problème se rapporte à quand setNeedsDisplay est appelé une fois le counter == 4 . Il semble que le code attende jusqu'à ce que 4 nouveaux points de contact soient reçus avant de tracer une ligne courbe. Idéalement, une ligne courbe est dessinée à chaque sharepoint contact (c.-à-d. Compteur == 1), éliminant le retard. (Changer de Counter == 1 ne semble pas fonctionner.)

Je suis perdu et je ne sais pas comment mettre à jour le code pour l'améliorer davantage afin de supprimer ce léger décalage mais conserver les lignes courbes. Qu'est-ce qui doit changer dans le code ci-dessous pour supprimer ce décalage?

 // Swift 2 code below tested using Xcode 7.0.1. class drawView: UIView { var path:UIBezierPath? var incrementalImage:UIImage? var points = [CGPoint?](count: 5, repeatedValue: nil) var counter:Int? var infoView:UIView = UIView() var strokeColor:UIColor? required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.multipleTouchEnabled = false self.backgroundColor = UIColor.whiteColor() path = UIBezierPath() path?.lineWidth = 20.0 strokeColor = UIColor.darkGrayColor() path?.lineCapStyle = CGLineCap.Round } override init(frame: CGRect) { super.init(frame: frame) self.multipleTouchEnabled = false path = UIBezierPath() path?.lineWidth = 20.0 } override func drawRect(rect: CGRect) { incrementalImage?.drawInRect(rect) strokeColor?.setStroke() path?.stroke() } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { counter = 0 let touch: AnyObject? = touches.first points[0] = touch!.locationInView(self) infoView.removeFromSuperview() } override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch: AnyObject? = touches.first let point = touch!.locationInView(self) counter = counter! + 1 points[counter!] = point if counter == 4{ points[3]! = CGPointMake((points[2]!.x + points[4]!.x)/2.0, (points[2]!.y + points[4]!.y)/2.0) path?.moveToPoint(points[0]!) path?.addCurveToPoint(points[3]!, controlPoint1: points[1]!, controlPoint2: points[2]!) self.setNeedsDisplay() points[0]! = points[3]! points[1]! = points[4]! counter = 1 } } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { self.drawBitmap() self.setNeedsDisplay() path?.removeAllPoints() counter = 0 } override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { self.touchesEnded(touches!, withEvent: event) } func drawBitmap(){ UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0.0) strokeColor?.setStroke() if((incrementalImage) == nil){ let rectPath:UIBezierPath = UIBezierPath(rect: self.bounds) UIColor.whiteColor().setFill() rectPath.fill() } incrementalImage?.drawAtPoint(CGPointZero) path?.stroke() incrementalImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } } 

Pour commencer, je crois que vous le faites mal. Cela fonctionne habituellement bien si vous voulez dessiner quelques lignes pas nesscarly par l'input des users mais pour les cercles, les lignes ondulées, les choses simples.

en utilisant:

 self.setNeedsDisplay() 

Vous redessinez TOUTES les lignes tous les jours! C'est un processeur dur et c'est pourquoi vous avez un décalage. Image l'user dessine quelques centaines de lignes puis dans un millier et chaque fois qu'il touche l'écran, il va redessiner toutes ces lignes.

D'ACCORD. Donc, ce que je recommand de faire est d'avoir 2 UIImageViews: 1) mainImageView – qui tiendra le dessin global. 2) tempImageView – que l'user utilisera pour dessiner.

Lorsque l'user touche / dessine "tempImageView", il dessine jusqu'à ce qu'il lâche l'écran puis fusionne "tempImageView" avec "mainImageView"

Voici un tutoriel sur:

http://www.raywenderlich.com/87899/make-simple-drawing-app-uikit-swift