如何在iOS Swift中绘制圆圈?

时间:2015-04-13 23:59:40

标签: 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

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

最简单的方法是什么?

9 个答案:

答案 0 :(得分:191)

你可以画一个圆圈:

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的角落,而不是在视图中添加圆圈。


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

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


但请注意,这是一个非常方便的电话

让circlePath = UIBezierPath(ovalInRect:rect)

完成了制作路径的所有工作。 (不要忘记插入线条粗细,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


在斯威夫特的这些日子里,你当然会使用

@IBDesignable

@IBInspectable

通过这种方式,您可以在故事板中实际 查看和更改渲染!

如您所见,它实际上为故事板上的Inspector添加了新功能,您可以在故事板上进行更改:

enter image description here

这是代码......

// 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(它是正方形,并且您在Storyboard中设置为红色)并且您只想将其转换为红色圆圈,则可以执行以下操作:

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

答案 1 :(得分:7)

如果你想使用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);

答案 2 :(得分:3)

更新@Dario的Xcode 8.2.2,Swift 3.x的代码方法。注意在故事板中,将背景颜色设置为"清除"避免在UIView广场上出现黑色背景:

using namespace std::string_literals;
logStream("Hello, "s + "world!");

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

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

答案 3 :(得分:3)

创建一个UIView类,并将其代码分配给一个简单的圆圈

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


    }


}

答案 4 :(得分:2)

迅速4 版本的已接受答案:

@IBDesignable
class CircledDotView: UIView {

    @IBInspectable var mainColor: UIColor = .white {
        didSet { print("mainColor was set here") }
    }
    @IBInspectable var ringColor: UIColor = .black {
        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)
    }
}

答案 5 :(得分:1)

我觉得Core Graphics对于 Swift 3 来说非常简单:

class LegoCache(object):
    def __init__(self):
        self.cache = Cache()

    def store(self, weight, color):
        self.cache.store((weight, color))
        # or just self.cache.store(weight, color) if you use the *args implementation

答案 6 :(得分:1)

这是我使用Swift 5和Core Graphics的版本。

我创建了一个画两个圆的类。第一个圆是使用addEllipse()创建的。它将椭圆变成正方形,从而创建一个圆。我发现没有功能addCircle()令人惊讶。第二个圆是使用addArc()的2pi弧度

创建的
import UIKit

@IBDesignable
class DrawCircles: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        guard let context = UIGraphicsGetCurrentContext() else {
            print("could not get graphics context")
            return
        }

        context.setLineWidth(2)

        context.setStrokeColor(UIColor.blue.cgColor)

        context.addEllipse(in: CGRect(x: 30, y: 30, width: 50.0, height: 50.0))

        context.strokePath()

        context.setStrokeColor(UIColor.red.cgColor)

        context.beginPath() // this prevents a straight line being drawn from the current point to the arc

        context.addArc(center: CGPoint(x:100, y: 100), radius: 20, startAngle: 0, endAngle: 2.0*CGFloat.pi, clockwise: false)

        context.strokePath()
    }
}

在ViewController的didViewLoad()中添加以下内容:

let myView = DrawCircles(frame: CGRect(x: 50, y: 50, width: 300, height: 300))

self.view.addSubview(myView)

它运行时应如下所示。希望您喜欢我的解决方案!

enter image description here

答案 7 :(得分:0)

在视图中添加加载

    //Circle Points

     var CircleLayer   = CAShapeLayer() 

    let center = CGPoint (x: myCircleView.frame.size.width / 2, y: myCircleView.frame.size.height / 2)
    let circleRadius = myCircleView.frame.size.width / 2
    let circlePath = UIBezierPath(arcCenter: center, radius: circleRadius, startAngle: CGFloat(M_PI), endAngle: CGFloat(M_PI * 4), clockwise: true)
    CircleLayer.path = circlePath.cgPath
   CircleLayer.strokeColor = UIColor.red.cgColor
    CircleLayer.fillColor = UIColor.blue.cgColor
    CircleLayer.lineWidth = 8
    CircleLayer.strokeStart = 0
    CircleLayer.strokeEnd  = 1
    Self.View.layer.addSublayer(CircleLayer)

答案 8 :(得分:0)

一个简单的函数,使用乘数百分比在窗口框架的中间绘制一个圆

/// CGFloat is a multiplicator from self.view.frame.width
func drawCircle(withMultiplicator coefficient: CGFloat) {

    let radius = self.view.frame.width / 2 * coefficient

    let circlePath = UIBezierPath(arcCenter: self.view.center, radius: radius, 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
    shapeLayer.strokeColor = UIColor.darkGray.cgColor
    shapeLayer.lineWidth = 2.0

    view.layer.addSublayer(shapeLayer)
}