Ancho de línea y color incorrecto con UIBezierPath

Estoy teniendo un problema extraño con UIBezierPath, donde mi color y el ancho de línea no se muestran correctamente.

Estoy dibujando una serie de líneas (como una regla) con gradaciones mayores y menores. Las gradaciones principales son líneas con mayor longitud …

Gradación mayor: Color Rojo y Ancho de línea: 2.0 Gradación menor: Color Amarillo y Ancho de línea: 0.0 (línea más delgada según especificación)

deslizador

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.networking 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 } 

Básicamente, quiero que las líneas más largas tengan un color ROJO y un ancho de línea más grueso, pero los colors se ven invertidos y el ancho de la línea no parece tener ningún impacto.

Como se puede ver en la function de dibujo, no hay rojo UIColor asociado a las longitudes de línea más pequeñas. He intentado configurar el color del trazo antes de crear la ruta, pero eso no parece funcionar.

Hay un par de problemas aquí, pero el problema key es que drawLine está creando un UIBezierPath y está llamando a strokePath . Pero strokePath no acaricia ese UIBezierPath que acaba de crear, sino la ruta anterior agregada a ese context. Pero dado que no agrega la línea al context hasta que regrese de drawLine , todo se desconecta en uno. Además, dado que está agregando todas esas líneas al context (en lugar de replace la ruta), está haciendo un montón de volver a dibujar las mismas líneas repetidamente.

Puede solucionarlo simplemente llamando a drawLine lugar de 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) ... } } 

Y drawLine no devuelve nada, pero en realidad solo lo dibuja:

 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.restreGState() } 

Tenga en count que estoy guardando y restaurando el context gráfico para que pueda dibujar una nueva ruta de segmento de línea cada vez. Además, dado que estoy acariciando la ruta del context, estoy llamando a setLineWidth en el context, no en la ruta. Además, no se muestra aquí, encontré que si acariciaba las líneas amarillas con un ancho de cero, no aparecían, así que usé 1:

ejemplo de imagen

Tenga en count que, si se tratara de una subclass UIView , podría simplificar esto más (simplemente UIBezierPath directamente el UIBezierPath lugar de jugar con CoreGraphics, podría hacerlo @IBDesignable , etc.). Pero si va a implementar draw(in:) , probablemente haría algo como lo anterior.