覆盖绘图应用程序的 drawRect
Overriding drawRect for drawing app
我正在构建一个演示绘图应用程序。我正在使用 touchesMoved:withEvent 来收集我的点并将它们添加到 CGMutablePathRef。为了描边路径,我覆盖了 DrawRect,将路径添加到上下文并描边路径:
override func drawRect(rect: CGRect) {
self.backgroundColor?.set()
UIRectFill(rect)
let context : CGContextRef = UIGraphicsGetCurrentContext()
for line in pathArray {
CGContextAddPath(context, line.structPath)
CGContextSetLineWidth(context, line.structLineWidth)
CGContextSetStrokeColorWithColor(context, line.structLineColor.CGColor)
CGContextSetAlpha(context, lineOpacity)
}
CGContextSetLineCap(context, kCGLineCapRound)
CGContextStrokePath(context)
self.empty = false
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first as UITouch! {
previousPoint = touch.previousLocationInView(self)
previousPreviousPoint = touch.previousLocationInView(self)
currentPoint = touch.locationInView(self)
}
self.touchesMoved(touches, withEvent: event)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first as UITouch! {
previousPreviousPoint = previousPoint
previousPoint = touch.previousLocationInView(self)
currentPoint = touch.locationInView(self)
let mid1 : CGPoint = getMidPoint(previousPoint, p2: previousPreviousPoint)
let mid2 : CGPoint = getMidPoint(currentPoint, p2: previousPoint)
let subpath : CGMutablePathRef = CGPathCreateMutable()
CGPathMoveToPoint(subpath, nil, mid1.x, mid1.y)
CGPathAddQuadCurveToPoint(subpath, nil, previousPoint.x, previousPoint.y, mid2.x, mid2.y)
let bounds : CGRect = CGPathGetBoundingBox(subpath)
let drawBox : CGRect = CGRectInset(bounds, -2.0 * lineWidth, -2.0 * lineWidth)
let newLine = line(newPath: subpath)
pathArray.append(newLine)
self.setNeedsDisplayInRect(drawBox)
}
}
以上代码按预期工作,只是我看到了意外结果。 "draw box" 获取 bandbox 并设置 CGRectInset 更改已绘制的其他路径的 lineColor:
我明白(有点)为什么会这样,但找不到解决这个问题的办法。如有任何建议,我们将不胜感激!
你想分别描边每条路径,像这样:
override func drawRect(rect: CGRect) {
let context : CGContextRef = UIGraphicsGetCurrentContext()
// Set parameters in the context that are the same for all lines
CGContextSetLineCap(context, kCGLineCapRound)
CGContextSetAlpha(context, lineOpacity)
for line in pathArray {
// Set parameters in the context that are specific to this line
CGContextSetLineWidth(context, line.structLineWidth)
CGContextSetStrokeColorWithColor(context, line.structLineColor.CGColor)
// Add the line's path to the context's current path:
CGContextAddPath(context, line.structPath)
// And stroke it.
CGContextStrokePath(context)
// (This has the side effect of clearing the context's current path.)
}
}
CGContext 跟踪当前路径。将其视为您无法直接访问的 CGMutablePath
。您可以通过调用 CGContextAddPath
或许多其他函数来影响它。
CGContext 的当前路径实际上是不可见的,直到您通过调用 CGContextStrokePath
之类的函数告诉上下文绘制它。届时上下文会根据当前路径和上下文中的其他值(描边颜色、alpha、线宽等)判断要画什么,然后画出来。
您的代码将每一行的路径添加到当前路径中,因此您最终得到的当前路径包含多个断开连接的子路径。然后你在最后调用了一次 CGContextStrokePath
,所有这些子路径都是使用你最近设置的参数值绘制的。所以你只看到了最后一行的宽度和颜色。
我正在构建一个演示绘图应用程序。我正在使用 touchesMoved:withEvent 来收集我的点并将它们添加到 CGMutablePathRef。为了描边路径,我覆盖了 DrawRect,将路径添加到上下文并描边路径:
override func drawRect(rect: CGRect) {
self.backgroundColor?.set()
UIRectFill(rect)
let context : CGContextRef = UIGraphicsGetCurrentContext()
for line in pathArray {
CGContextAddPath(context, line.structPath)
CGContextSetLineWidth(context, line.structLineWidth)
CGContextSetStrokeColorWithColor(context, line.structLineColor.CGColor)
CGContextSetAlpha(context, lineOpacity)
}
CGContextSetLineCap(context, kCGLineCapRound)
CGContextStrokePath(context)
self.empty = false
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first as UITouch! {
previousPoint = touch.previousLocationInView(self)
previousPreviousPoint = touch.previousLocationInView(self)
currentPoint = touch.locationInView(self)
}
self.touchesMoved(touches, withEvent: event)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first as UITouch! {
previousPreviousPoint = previousPoint
previousPoint = touch.previousLocationInView(self)
currentPoint = touch.locationInView(self)
let mid1 : CGPoint = getMidPoint(previousPoint, p2: previousPreviousPoint)
let mid2 : CGPoint = getMidPoint(currentPoint, p2: previousPoint)
let subpath : CGMutablePathRef = CGPathCreateMutable()
CGPathMoveToPoint(subpath, nil, mid1.x, mid1.y)
CGPathAddQuadCurveToPoint(subpath, nil, previousPoint.x, previousPoint.y, mid2.x, mid2.y)
let bounds : CGRect = CGPathGetBoundingBox(subpath)
let drawBox : CGRect = CGRectInset(bounds, -2.0 * lineWidth, -2.0 * lineWidth)
let newLine = line(newPath: subpath)
pathArray.append(newLine)
self.setNeedsDisplayInRect(drawBox)
}
}
以上代码按预期工作,只是我看到了意外结果。 "draw box" 获取 bandbox 并设置 CGRectInset 更改已绘制的其他路径的 lineColor:
我明白(有点)为什么会这样,但找不到解决这个问题的办法。如有任何建议,我们将不胜感激!
你想分别描边每条路径,像这样:
override func drawRect(rect: CGRect) {
let context : CGContextRef = UIGraphicsGetCurrentContext()
// Set parameters in the context that are the same for all lines
CGContextSetLineCap(context, kCGLineCapRound)
CGContextSetAlpha(context, lineOpacity)
for line in pathArray {
// Set parameters in the context that are specific to this line
CGContextSetLineWidth(context, line.structLineWidth)
CGContextSetStrokeColorWithColor(context, line.structLineColor.CGColor)
// Add the line's path to the context's current path:
CGContextAddPath(context, line.structPath)
// And stroke it.
CGContextStrokePath(context)
// (This has the side effect of clearing the context's current path.)
}
}
CGContext 跟踪当前路径。将其视为您无法直接访问的 CGMutablePath
。您可以通过调用 CGContextAddPath
或许多其他函数来影响它。
CGContext 的当前路径实际上是不可见的,直到您通过调用 CGContextStrokePath
之类的函数告诉上下文绘制它。届时上下文会根据当前路径和上下文中的其他值(描边颜色、alpha、线宽等)判断要画什么,然后画出来。
您的代码将每一行的路径添加到当前路径中,因此您最终得到的当前路径包含多个断开连接的子路径。然后你在最后调用了一次 CGContextStrokePath
,所有这些子路径都是使用你最近设置的参数值绘制的。所以你只看到了最后一行的宽度和颜色。