如何在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) } }