如何在iOS Swift中绘制圆圈?

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

这是我现在所拥有的,但显然不是正确的做法。

最简单的方法是什么?

你可以用这个画一个圆:

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) 

用你发布的代码裁剪UIView的angular落,而不是向视图添加一个圆。


以下是使用该方法的完整示例:

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

在这里输入图像说明


但请注意,有一个令人难以置信的方便的电话

让circlePath = UIBezierPath(ovalInRect:rect)

做所有的path工作。 (不要忘记插入它的线条粗细, 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) } 

在这里输入图像说明


在Swift的这些日子里,你肯定会用到

@IBDesignable

@IBInspectable

通过这种方式,您可以在Storyboard中实际看到并更改渲染!

如您所见,它实际上向故事板上的检查器添加了新function,您可以在故事板上更改这些function:

在这里输入图像说明

这是代码…

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

最后,请注意,如果你有一个UIView(这是一个方形的,你在故事板中设置为红色),你只需要把它转换成一个红色的圆形,你可以做到以下几点:

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

如果你想使用UIView绘制它,那么你需要使高度或宽度的半径。

所以只需改变:

 block.layer.cornerRadius = 9 

至:

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

但是,您需要使高度和宽度相同。 如果你想使用coregraphics,那么你会想要做这样的事情:

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

更新Xcode 8.2.2,Swift 3.x的Dario的代码方法 注意到在故事板中,将背景颜色设置为“清除”以避免正方形UIView中出现黑色背景:

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

如果你想控制开始和结束angular度:

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