ssa*_*ngi 5 ios uibezierpath swift3
我在使用UIBezierPath时遇到了一个奇怪的问题,我的颜色和线宽没有正确呈现.
我正在绘制一系列具有主要和次要渐变的线条(如尺子).主要渐变是长度更长的线条......
主要渐变:颜色红色和线宽:2.0次要渐变:颜色黄色和线宽:0.0(根据规格最细的线)
override func draw(in ctx: CGContext) {
if let _ = cameraControlSlider {
guard gradationValues.count >= 0 else {
return
}
let frame = CGRect(x: insetBy, y: 0, width: bounds.width - insetBy, height: bounds.height)
ctx.clear(frame)
let startx = Int(frame.origin.x)
let endx = Int(frame.origin.x + frame.width)
let incrementWidth = (endx - startx) / (gradationValuesOnScreen + 1)
var counter = 1
var x = startx + counter * incrementWidth
while x < endx {
var y1 = Int(frame.origin.y)
var y2 = Int(frame.origin.y) + Int(frame.height)
var lineWidth: Float = 2.0
var color = UIColor.red
if counter % majorGradationInterval != 1 {
y1 = Int(frame.origin.y) + Int(frame.height / 4)
y2 = Int(frame.origin.y + frame.height) - Int(frame.height / 4)
lineWidth = 0.0
color = UIColor.yellow
}
ctx.addPath(drawLine(in: ctx, x1: x, y1: y1, x2: x, y2: y2, color: color, lineWidth: lineWidth))
counter += 1
x = startx + counter * incrementWidth
}
}
}
func drawLine(in ctx: CGContext, x1: Int, y1: Int, x2: Int, y2: Int, color: UIColor, lineWidth: Float) -> CGPath {
let path = UIBezierPath()
ctx.setStrokeColor(color.cgColor)
path.lineWidth = CGFloat(lineWidth)
path.move(to: CGPoint(x: x1, y: y1))
path.addLine(to: CGPoint(x: x2, y: y2))
path.close()
ctx.strokePath()
return path.cgPath
}
Run Code Online (Sandbox Code Playgroud)
基本上我希望较长的线条具有红色和较粗的线宽,但颜色看起来是倒置的,线条宽度似乎没有任何影响.
从绘图功能可以看出,没有UIColor红色与较小的线长度相关联.我已经尝试在创建路径之前设置笔触颜色,但这似乎不起作用.
这里有几个问题,但关键问题是drawLine
创建UIBezierPath
并调用strokePath
. 但strokePath
不会抚摸UIBezierPath
您刚刚创建的路径,而是抚摸添加到该上下文的先前路径。但由于您直到从 返回后才将该行添加到上下文中drawLine
,因此所有内容都会减少一。另外,由于您将所有这些行添加到上下文中(而不是替换路径),因此您正在重复地重绘相同的行。
您可以通过调用drawLine
而不是修复它addPath(drawLine(...)
:
override func draw(in ctx: CGContext) {
...
while x < endx {
...
drawLine(in: ctx, x1: x, y1: y1, x2: x, y2: y2, color: color, lineWidth: lineWidth)
...
}
}
Run Code Online (Sandbox Code Playgroud)
并且drawLine
不返回任何内容,但实际上只是绘制它:
func drawLine(in ctx: CGContext, x1: Int, y1: Int, x2: Int, y2: Int, color: UIColor, lineWidth: Float) {
let path = UIBezierPath()
ctx.saveGState()
ctx.setStrokeColor(color.cgColor)
ctx.setLineWidth(CGFloat(lineWidth))
path.move(to: CGPoint(x: x1, y: y1))
path.addLine(to: CGPoint(x: x2, y: y2))
ctx.addPath(path.cgPath)
ctx.strokePath()
ctx.restoreGState()
}
Run Code Online (Sandbox Code Playgroud)
请注意,我正在保存和恢复图形上下文,以便每次都可以绘制新的线段路径。另外,由于我正在抚摸上下文的路径,因此我正在调用setLineWidth
上下文,而不是路径。另外,这里没有显示,我发现如果我抚摸宽度为零的黄线,它们不会出现,所以我使用了1:
请注意,如果这是一个UIView
子类,您可以进一步简化它(只需UIBezierPath
直接描边而不是与 CoreGraphics 搞乱,您可以制作它@IBDesignable
,等等)。但如果你要实现draw(in:)
,我可能会做类似上面的事情。