Swift - 使用CGContext用手指画图
Swift - Using CGContext to draw with finger
我正在尝试制作一个绘图应用程序。我有一个自定义 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)
}
}
然而,当我 运行 它时,我得到的只是一个蓝点跟随我的手指,但没有线条?
我做错了什么?
两件事:
调用 self.setNeedsDisplay
不会立即调用 drawRect
。它只是设置一个标志,以便 drawRect
在不久的将来被调用。由于您在那之后立即将 lastPoint
设置为 currentPoint
,因此当调用 drawRect
时,lastPoint
始终等于 currentPoint
.
drawRect
每次调用时都会重新绘制整个视图,因此您最多只能看到最近的一行。如果你解决了问题 1,你的手指后面会有一条短线而不是一个点。如果你想看到整个轨迹,你需要将点存储在一个数组中,该数组是你视图的 属性,然后画线连接 drawRect
中的所有点。
您好,我做了一些简单的更改并修复了您的代码,希望它对以后的人有所帮助(代码已更新为 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
}
}
}
}
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()
}
}
}
我正在尝试制作一个绘图应用程序。我有一个自定义 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)
}
}
然而,当我 运行 它时,我得到的只是一个蓝点跟随我的手指,但没有线条?
我做错了什么?
两件事:
调用
self.setNeedsDisplay
不会立即调用drawRect
。它只是设置一个标志,以便drawRect
在不久的将来被调用。由于您在那之后立即将lastPoint
设置为currentPoint
,因此当调用drawRect
时,lastPoint
始终等于currentPoint
.drawRect
每次调用时都会重新绘制整个视图,因此您最多只能看到最近的一行。如果你解决了问题 1,你的手指后面会有一条短线而不是一个点。如果你想看到整个轨迹,你需要将点存储在一个数组中,该数组是你视图的 属性,然后画线连接drawRect
中的所有点。
您好,我做了一些简单的更改并修复了您的代码,希望它对以后的人有所帮助(代码已更新为 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
}
}
}
}
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()
}
}
}