2015-04-13 22 views
45
let block = UIView(frame: CGRectMake(cellWidth-25, cellHeight/2-8, 16, 16)) 
block.backgroundColor = UIColor(netHex: 0xff3b30) 
block.layer.cornerRadius = 9 
block.clipsToBounds = true 

Questo è quello che ho adesso, ma ovviamente non è il modo giusto per farlo.Come disegnare un cerchio in iOS Swift?

Qual è il modo più semplice per farlo?

+0

Hai un numero di modi in cui puoi farlo, SpriteKit, Core Graphics, ecc. Probabilmente dovresti inchiodarlo un po 'di più per noi. –

+4

Non riesci a vedere il minimo motivo, a tutti, qualcuno voterebbe per chiudere questa domanda? – Fattie

+0

@Joe Sono abbastanza sicuro che puoi guadagnare punti come amministratore per determinate attività, comprese le domande di chiusura. Ciò probabilmente spiega il motivo per cui cinque persone sono citate mentre chiudevano la domanda quando (per quattro di esse) era già chiusa. –

risposta

157

È possibile disegnare un cerchio con questo:

Swift 2.2:

let circlePath = UIBezierPath(arcCenter: CGPoint(x: 100,y: 100), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true) 

    let shapeLayer = CAShapeLayer() 
    shapeLayer.path = circlePath.CGPath 

    //change the fill color 
    shapeLayer.fillColor = UIColor.clearColor().CGColor 
    //you can change the stroke color 
    shapeLayer.strokeColor = UIColor.redColor().CGColor 
    //you can change the line width 
    shapeLayer.lineWidth = 3.0 

    view.layer.addSublayer(shapeLayer) 

Swift 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 il codice che hai postato stai ritagliando gli angoli di UIView, non aggiungendo un cerchio alla vista.


Ecco un esempio completo di utilizzo di tale metodo:

// make the UIView a ring of color 
import UIKit 
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) 
     } 
    } 

enter image description here


Nota però c'è una chiamata incredibilmente utile

lasciare circlePath = UIBezierPath (ovalInRect: rect)

che fa tutto il lavoro di fare il percorso. (Non dimenticare di inserto per lo spessore della linea, che è anche incredibilmente facile 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) 
    } 

enter image description here


In pratica in questi giorni a Swift, si sarebbe certamente utilizzare

@IBDesignable

e

@IBInspectable

In questo modo è possibile effettivamente visualizzare e modificare il rendering, in Storyboard!

Come si può vedere, in realtà aggiunge nuove funzionalità per l'ispettore sul Storyboard, che è possibile modificare sul Storyboard:

enter image description here

Ecco il codice ...

// Dot with border, which you can control completely in Storyboard 
import UIKit 
@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) 
     } 
    } 

Infine, si noti che se si dispone di un UIView (che è quadrato, e che si imposta per dire rosso in Storyboard) e si vuole semplicemente trasformarlo in un cerchio rosso, si può semplicemente effettuare le seguenti operazioni:

// It makes a UIView into a circular dot of color 
import UIKit 
class Dot:UIView 
    { 
    override func layoutSubviews() 
     { layer.cornerRadius = bounds.size.width/2; } 
    } 
+0

Grazie per la risposta! Conoscete la differenza perfetta tra l'uso di cornerRadius e BezierPath? Semplicemente curioso :) – hyouuu

+1

'M_PI' è deprecato. Ora è 'Double.pi' (in Swift 3) – KVISH

2

Se si desidera utilizzare un UIView per disegnarlo, è necessario impostare il raggio/dell'altezza o della larghezza.

quindi basta cambiare:

block.layer.cornerRadius = 9 

a:

block.layer.cornerRadius = block.frame.width/2 

Avrai bisogno di rendere l'altezza e la larghezza lo stesso però. Se si desidera utilizzare CoreGraphics, quindi ti consigliamo di fare qualcosa di simile:

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

Aggiornamento @ approccio codice di Dario per Xcode 8.2.2, 3.x. Swift Notando che in storyboard, impostare il colore di sfondo a "chiaro" per evitare uno sfondo nero in UIView piazza:

import UIKit 
@IBDesignable 
class Dot:UIView 
{ 
    @IBInspectable var mainColor: UIColor = UIColor.clear 
     { 
     didSet { print("mainColor was set here") } 
    } 
    @IBInspectable var ringColor: UIColor = UIColor.clear 
     { 
     didSet { print("bColor was set here") } 
    } 
    @IBInspectable var ringThickness: CGFloat = 4 
     { 
     didSet { print("ringThickness was set here") } 
    } 


    @IBInspectable var isSelected: Bool = true 

    override func draw(_ rect: CGRect) 
    { 

     let dotPath = UIBezierPath(ovalIn: rect) 
     let shapeLayer = CAShapeLayer() 
     shapeLayer.path = dotPath.cgPath 
     shapeLayer.fillColor = mainColor.cgColor 
     layer.addSublayer(shapeLayer) 

     if (isSelected) { drawRingFittingInsideView(rect: rect) } 
    } 

    internal func drawRingFittingInsideView(rect: CGRect)->() 
    { 
     let hw:CGFloat = ringThickness/2 
     let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw)) 

     let shapeLayer = CAShapeLayer() 
     shapeLayer.path = circlePath.cgPath 
     shapeLayer.fillColor = UIColor.clear.cgColor 
     shapeLayer.strokeColor = ringColor.cgColor 
     shapeLayer.lineWidth = ringThickness 
     layer.addSublayer(shapeLayer) 
    } 
} 

E se si desidera controllare gli angoli di inizio e fine:

import UIKit 
@IBDesignable 
class Dot:UIView 
{ 
    @IBInspectable var mainColor: UIColor = UIColor.clear 
     { 
     didSet { print("mainColor was set here") } 
    } 
    @IBInspectable var ringColor: UIColor = UIColor.clear 
     { 
     didSet { print("bColor was set here") } 
    } 
    @IBInspectable var ringThickness: CGFloat = 4 
     { 
     didSet { print("ringThickness was set here") } 
    } 


    @IBInspectable var isSelected: Bool = true 

    override func draw(_ rect: CGRect) 
    { 

     let dotPath = UIBezierPath(ovalIn: rect) 
     let shapeLayer = CAShapeLayer() 
     shapeLayer.path = dotPath.cgPath 
     shapeLayer.fillColor = mainColor.cgColor 
     layer.addSublayer(shapeLayer) 

     if (isSelected) { drawRingFittingInsideView(rect: rect) } 
    } 

    internal func drawRingFittingInsideView(rect: CGRect)->() 
    { 
     let halfSize:CGFloat = min(bounds.size.width/2, bounds.size.height/2) 
     let desiredLineWidth:CGFloat = ringThickness // your desired value 

     let circlePath = UIBezierPath(
      arcCenter: CGPoint(x: halfSize, y: halfSize), 
      radius: CGFloat(halfSize - (desiredLineWidth/2)), 
      startAngle: CGFloat(0), 
      endAngle:CGFloat(Double.pi), 
      clockwise: true) 

     let shapeLayer = CAShapeLayer() 
     shapeLayer.path = circlePath.cgPath 
     shapeLayer.fillColor = UIColor.clear.cgColor 
     shapeLayer.strokeColor = ringColor.cgColor 
     shapeLayer.lineWidth = ringThickness 
     layer.addSublayer(shapeLayer) 
    } 
} 
+0

Grazie per le traduzioni di Swift 3, mi ha risparmiato un sacco di tempo e test! – denisq91

0

Marchio un UIView di classe e assegnarlo questo codice per un semplice cerchio

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() 


    } 


} 
0

trovo core grafico di essere abbastanza semplice per Swift 3:

if let cgcontext = UIGraphicsGetCurrentContext() { 
    cgcontext.strokeEllipse(in: CGRect(x: center.x-diameter/2, y: center.y-diameter/2, width: diameter, height: diameter)) 
} 
Problemi correlati