使用swift 2在ios 8.4中连续绘制期间消除滞后延迟

时间:2016-02-04 09:04:39

标签: ios swift multi-touch

在这段代码中,我面临着滞后的问题和高CPU使用率。我创建了三个差异文件。

  1. 第一个DrawView.swift

    class DrawView: UIView {
    
    var lines: [Line] = []
    var firstPoint: CGPoint!
    var percentageOfXY:[String]=[]
    var viewWidth:CGFloat!
    var viewHeight:CGFloat!
    var drawColor:UIColor!
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
        viewWidth = frame.width
        viewHeight = frame.height
        let touch = touches.first as UITouch?
        let start = touch!.locationInView(self)
        let percentageX = round(((start.x)*100)/viewWidth*100)/100
        let percentageY = round(((start.y)*100)/viewHeight*100)/100
        firstPoint = CGPointMake(percentageX, percentageY)
    }
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
        viewWidth = frame.width
        viewHeight = frame.height
        let touch = touches.first as UITouch?
        let curr = touch!.locationInView(self)
        let percentageX = round(((curr.x)*100)/viewWidth*100)/100
        let percentageY = round(((curr.y)*100)/viewHeight*100)/100
        let lastPoint = CGPointMake(percentageX, percentageY)
        lines.append(Line(start: firstPoint, end: lastPoint, color: drawColor))
        firstPoint = lastPoint
        self.setNeedsDisplay()
    
    }
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)
    {
    
    }
    override func drawRect(rect: CGRect) {
    
        for line in lines
        {
            let context = UIGraphicsGetCurrentContext()
            CGContextSetLineCap(context, CGLineCap.Round)
            CGContextSetLineWidth(context,3)
            let startX = ((line.start.x)*viewWidth)/100
            let startY = ((line.start.y)*viewHeight)/100
            let endX = ((line.end.x)*viewWidth)/100
            let endY = ((line.end.y)*viewHeight)/100
            CGContextBeginPath(context)
            CGContextMoveToPoint(context, startX,startY)
    
            CGContextAddLineToPoint(context, endX,endY)
            CGContextSetStrokeColorWithColor(context,line.color.CGColor)
            CGContextStrokePath(context)
    
        }
    }
    }  
    
  2. 第二个用于以格式存储坐标的Line.swift。

    class Line 
    {
    var start: CGPoint!
    var end: CGPoint!
    var cord: [String]!
    var color:UIColor!
    init(start _start: CGPoint,end _end: CGPoint,color _color:UIColor)
    {
        start = _start
        end = _end
        color = _color
    }
    }
    
  3. 第三个用于颜色选择。

    @IBOutlet weak var drawView: DrawView!
    override func viewDidLoad() {
        super.viewDidLoad()
        drawView.backgroundColor = UIColor.clearColor()
    }
    
    @IBAction func redColor(sender: AnyObject) {
        let theDrawView = drawView as DrawView
        var color:UIColor!
        color = UIColor.redColor()
        theDrawView.drawColor = color
    }
    @IBAction func greenColor(sender: AnyObject) {
        let theDrawView = drawView as DrawView
        var color:UIColor!
        color = UIColor.greenColor()
        theDrawView.drawColor = color
    }
    @IBAction func blueColor(sender: AnyObject) {
        let theDrawView = drawView as DrawView
        var color:UIColor!
        color = UIColor.blueColor()
        theDrawView.drawColor = color
    }  
    
  4. 在这个我画画中,但是通过滞后的问题它画出直线。

1 个答案:

答案 0 :(得分:0)

几个问题:

  • 从你的循环中获取UIGraphicsGetCurrentContext。
  • 从你的循环中获取CGContextSetLineCap。
  • 从循环中获取CGContextSetLineWidth。
  • 完全杀死CGContextBeginPath - CGContextStrokePath会为你做这件事。
  • 您应该发明一个带有点数组的线对象,这样您就不必为每个小段设置颜色。 TouchesBegan..TouchesEnded将开始并完成其中一个线对象。 (如果允许多点触控,你必须更加小心,但它看起来不像你。)
  • 如果您修复上面的线对象,您将拥有一对嵌套循环。然后你将CGContextMoveToPoint移出内循环的前面,CGContextSetStrokeColorWithColor和CGContextStrokePath移出内循环的末尾。

但是现在你的真正问题是:在屏幕上移动手指很容易就能产生每秒几千个像素的交叉点。你的touchesMoved每秒只能被调用60次(更常见的是在iPad Pro上)。如果您希望草图看起来平滑,则必须“弥补”从未提供过的数据。请参阅维基百科上的Kochanek-Bartels或Catmull-Rom splines。