Swift - 使用CGContext用手指绘制

时间:2015-05-13 17:41:23

标签: ios swift uiview cgcontext

我正在尝试制作一个绘图应用。我有一个自定义的UIView:

class DrawView: UIView {

var touch : UITouch!
var lastPoint : CGPoint!
var currentPoint : CGPoint!

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    touch = touches.first as! UITouch
    lastPoint = touch.locationInView(self)
    println(lastPoint)
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    touch = touches.first as! UITouch
    currentPoint = touch.locationInView(self)

    self.setNeedsDisplay()

    lastPoint = currentPoint
}

override func drawRect(rect: CGRect) {
    var context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 5)
    CGContextSetStrokeColorWithColor(context, UIColor.blueColor().CGColor)
    CGContextSetLineCap(context, kCGLineCapRound)

    CGContextBeginPath(context)

    if lastPoint != nil {
        CGContextMoveToPoint(context, lastPoint.x, lastPoint.y)
        CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y)
    }

    CGContextStrokePath(context)
}

}

然而,当我运行它时,我得到的只是一个跟在我手指上的蓝点,但是没有线条?

我做错了什么?

3 个答案:

答案 0 :(得分:1)

两件事:

  1. 致电self.setNeedsDisplay并不会立即致电drawRect。它只是设置一个标志,以便在不久的将来调用drawRect。由于您在此之后立即将lastPoint设置为currentPoint,因此调用drawRectlastPoint始终等于currentPoint

  2. drawRect每次调用时都会重绘整个视图,所以最多只会看到最新的一行。如果你修复了问题1,你的手指后面会有一条短线而不是一个点。如果要查看整个轨迹,则需要将点存储在视图属性的数组中,然后绘制线以连接drawRect中的所有点。

答案 1 :(得分:1)

您好我做了一些简单的修改并修复了您的代码,希望它能在将来帮助某人(代码更新为 Swift 3 ):

class DrawView: UIView {

    var touch : UITouch!
    var lineArray : [[CGPoint]] = [[CGPoint]()]
    var index = -1

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        touch = touches.first! as UITouch
        let lastPoint = touch.location(in: self)

        index += 1
        lineArray.append([CGPoint]())
        lineArray[index].append(lastPoint)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        touch = touches.first! as UITouch
        let currentPoint = touch.location(in: self)

        self.setNeedsDisplay()

        lineArray[index].append(currentPoint)
    }

    override func draw(_ rect: CGRect) {

        if(index >= 0){
            let context = UIGraphicsGetCurrentContext()
            context!.setLineWidth(5)
            context!.setStrokeColor((UIColor(red:0.00, green:0.38, blue:0.83, alpha:1.0)).cgColor)
            context!.setLineCap(.round)

            var j = 0
            while( j <= index ){
                context!.beginPath()
                var i = 0
                context?.move(to: lineArray[j][0])
                while(i < lineArray[j].count){
                    context?.addLine(to: lineArray[j][i])
                    i += 1
                }
                context!.strokePath()
                j += 1
            }
        }
    }
}

答案 2 :(得分:0)

marcomoreira92和Keuha的版本对我有用,但是我不太喜欢使用索引。因此,这是一个替代版本,已在Swift 4.2中进行了测试:

class DrawView: UIView {

    var lineArray: [[CGPoint]] = [[CGPoint]]()

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let firstPoint = touch.location(in: self)
        lineArray.append([CGPoint]())
        lineArray[lineArray.count - 1].append(firstPoint)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let currentPoint = touch.location(in: self)
        lineArray[lineArray.count - 1].append(currentPoint)
        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(5)
        context?.setStrokeColor(UIColor.black.cgColor)
        context?.setLineCap(.round)

        for line in lineArray {
            guard let firstPoint = line.first else { continue }
            context?.beginPath()
            context?.move(to: firstPoint)
            for point in line.dropFirst() {
                context?.addLine(to: point)
            }
            context?.strokePath()
        }
    }
}