在Swift中优化屏幕反馈绘制立方贝塞尔曲线

时间:2015-12-15 16:07:21

标签: ios swift optimization drawing

以下代码在用户将手指移过屏幕时绘制曲线。用于绘制三次贝塞尔曲线的方法是addCurveToPoint。然而,这种方法需要一个完整的1 .. 2 .. 3 .. 4 ..触摸点才能在屏幕上绘制曲线。这种方法会在屏幕上产生非常短但明显的滞后反馈,因为在收集新的触摸点时没有绘制任何内容。

使用代码示例/ s,可以在下面的代码中引入什么新的代码/编辑来绘制例如临时线,同时收集触点1 .. 2 .. 3 ..一旦删除临时线画出适当的曲线,以便立即开始绘制印象?

或者,有哪些其他技术可用于为用户提供即时反馈,并且即使在正确绘制触摸点之前仍然正在收集触摸点,也会在屏幕上开始展示?

  

注意,该解决方案必须适用于iOS7,iOS8和iOS9(即   iOS9中的高级触控处理功能不合适。)

// 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()
}
}

1 个答案:

答案 0 :(得分:2)

当第一个点可用时,绘制低阶Beziers怎么样?

  • 2个点定义线性贝塞尔曲线(即线段),

  • 3个点定义了二次贝塞尔曲线。

此外,您可以考虑橡皮筋,即在最后一个点仍在移动时重绘曲线(前者保持固定),直到您修复它并开始移动另一个。