Verzögerung beim Zeichnen von glatten UIBezierPath-Linien in Swift beseitigen
Der unten stehende Code zeichnet durch Überschreiben von Berührungen glatte, gekrümmte Linien, es treten jedoch Verzögerungen oder Latenzen auf. Der Code verwendetaddCurveToPoint
und ruftsetNeedsDisplay
nach jeweils 4 Berührungspunkten, was zu einem unruhigen Erscheinungsbild führt, da die Zeichnung mit den Fingerbewegungen nicht Schritt hält. Um die Verzögerung oder wahrgenommene Latenz zu beseitigen, können die Berührungspunkte 1, 2, 3 (die zu Berührungspunkt 4 führen) vorübergehend mit @ gefüllt werdeaddQuadCurveToPoint
undaddLineToPoint
.
Wie kann dies tatsächlich im Code erreicht werden, um wahrgenommene Verzögerungen durch die Verwendung einer temporären Linie und einer QuadCurved-Linie zu beseitigen, bevor eine endgültige Curved-Linie angezeigt wird?
Wenn die unten stehende Klasse an eine @ angehängt iUIView
(z. B. viewOne oderself
), wie mache ich eine Kopie der Zeichnung auf eine andereUIView
außerhalb der Klasse (z. B. viewTwo) nachtouchesEnded
?
// ViewController.swift
import UIKit
class drawSmoothCurvedLinesWithLagging: UIView {
let path=UIBezierPath()
var incrementalImage:UIImage?
var points = [CGPoint?](count: 5, repeatedValue: nil)
var counter:Int?
var strokeColor:UIColor?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect) {
autoreleasepool {
incrementalImage?.drawInRect(rect)
strokeColor = UIColor.blueColor()
strokeColor?.setStroke()
path.lineWidth = 20
path.lineCapStyle = CGLineCap.Round
path.stroke()
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
counter = 0
let touch: AnyObject? = touches.first
points[0] = touch!.locationInView(self)
}
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 == 2{
//use path.addLineToPoint ?
//use self.setNeedsDisplay() ?
}
if counter == 3{
//use path.addQuadCurveToPoint ?
//use self.setNeedsDisplay() ?
}
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()
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}