Saltar al contenido

¿Cómo dibujo un círculo en iOS Swift?

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 el drawRect método. Utilizar layoutSubview 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 UIViewsin 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)
     

Un círculo delineado en rojo y relleno de amarillo sobre un fondo amarillo.


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)

Elipses (en forma de óvalo) delineadas en rojo y rellenas de amarillo sobre un fondo amarillo.


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:

Inspector de atributos del guión gráfico de Xcode con campos personalizados.

/// 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);

Calificaciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *