Leila, miembro de este gran equipo, nos hizo el favor de redactar este enunciado porque controla a la perfección el tema.
Solución:
¡ADVERTENCIA! Esta es una solución incorrecta. las capas se agregan infinitamente en el
drawRect
método (cada vez que se dibuja la vista). NUNCA debe agregar capas en eldrawRect
método. UtilizarlayoutSubview
en lugar de.
Puedes dibujar un círculo con esto (Rápido 3.0+):
let circlePath = UIBezierPath(arcCenter: CGPoint(x: 100, y: 100), radius: CGFloat(20), startAngle: CGFloat(0), endAngle: CGFloat(Double.pi * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
// Change the fill color
shapeLayer.fillColor = UIColor.clear.cgColor
// You can change the stroke color
shapeLayer.strokeColor = UIColor.red.cgColor
// You can change the line width
shapeLayer.lineWidth = 3.0
view.layer.addSublayer(shapeLayer)
Con el código que ha publicado, está recortando las esquinas del UIView
sin agregar un círculo a la vista.
Aquí hay un ejemplo completo del uso de ese método:
/// A special UIView displayed as a ring of color
class Ring: UIView
override func drawRect(rect: CGRect)
drawRingFittingInsideView()
internal func drawRingFittingInsideView() -> ()
let halfSize:CGFloat = min( bounds.size.width/2, bounds.size.height/2)
let desiredLineWidth:CGFloat = 1 // your desired value
let circlePath = UIBezierPath(
arcCenter: CGPoint(x:halfSize,y:halfSize),
radius: CGFloat( halfSize - (desiredLineWidth/2) ),
startAngle: CGFloat(0),
endAngle:CGFloat(M_PI * 2),
clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.CGPath
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = UIColor.redColor().CGColor
shapeLayer.lineWidth = desiredLineWidth
layer.addSublayer(shapeLayer)
Tenga en cuenta, sin embargo, hay una llamada increíblemente útil:
let circlePath = UIBezierPath(ovalInRect: rect)
que hace todo el trabajo de hacer el camino. (No olvide insertarlo para el grosor de la línea, que también es increíblemente fácil con CGRectInset
.)
internal func drawRingFittingInsideView(rect: CGRect)
let desiredLineWidth:CGFloat = 4 // Your desired value
let hw:CGFloat = desiredLineWidth/2
let circlePath = UIBezierPath(ovalInRect: CGRectInset(rect,hw,hw))
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.CGPath
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = UIColor.redColor().CGColor
shapeLayer.lineWidth = desiredLineWidth
layer.addSublayer(shapeLayer)
En la práctica estos días en Swift, ciertamente usarías @IBDesignable
y @IBInspectable
. Usando estos puedes realmente ver y cambiar la representación, en Storyboard!
Como puede ver, en realidad agrega nuevas funciones al Inspector en el Guión gráfico, que puede cambiar en el Guión gráfico:
/// A dot with a border, which you can control completely in Storyboard
@IBDesignable class Dot: UIView
@IBInspectable var mainColor: UIColor = UIColor.blueColor()
didSet
print("mainColor was set here")
@IBInspectable var ringColor: UIColor = UIColor.orangeColor()
didSet
print("bColor was set here")
@IBInspectable var ringThickness: CGFloat = 4
didSet
print("ringThickness was set here")
@IBInspectable var isSelected: Bool = true
override func drawRect(rect: CGRect)
let dotPath = UIBezierPath(ovalInRect:rect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = dotPath.CGPath
shapeLayer.fillColor = mainColor.CGColor
layer.addSublayer(shapeLayer)
if (isSelected)
drawRingFittingInsideView(rect)
internal func drawRingFittingInsideView(rect: CGRect)
let hw:CGFloat = ringThickness/2
let circlePath = UIBezierPath(ovalInRect: CGRectInset(rect,hw,hw) )
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.CGPath
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = ringColor.CGColor
shapeLayer.lineWidth = ringThickness
layer.addSublayer(shapeLayer)
Por último, tenga en cuenta que si tiene un UIView
(que es cuadrado y que configuraste para que diga rojo en Storyboard) y simplemente quieres convertirlo en un círculo rojo, puedes hacer lo siguiente:
// Makes a UIView into a circular dot of color
class Dot: UIView
override func layoutSubviews()
layer.cornerRadius = bounds.size.width/2
Haga una clase UIView y asígnele este código para un círculo simple
import UIKit
@IBDesignable
class DRAW: UIView
override func draw(_ rect: CGRect)
var path = UIBezierPath()
path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100))
UIColor.yellow.setStroke()
UIColor.red.setFill()
path.lineWidth = 5
path.stroke()
path.fill()
Si desea usar una UIView para dibujarla, debe hacer el radio / de la altura o el ancho.
así que solo cambia:
block.layer.cornerRadius = 9
para:
block.layer.cornerRadius = block.frame.width / 2
Sin embargo, deberá hacer que la altura y el ancho sean iguales. Si desea utilizar coregraphics, querrá hacer algo como esto:
CGContextRef ctx= UIGraphicsGetCurrentContext();
CGRect bounds = [self bounds];
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;
CGContextSaveGState(ctx);
CGContextSetLineWidth(ctx,5);
CGContextSetRGBStrokeColor(ctx,0.8,0.8,0.8,1.0);
CGContextAddArc(ctx,locationOfTouch.x,locationOfTouch.y,30,0.0,M_PI*2,YES);
CGContextStrokePath(ctx);