如何在swift中从第一象限分割一个圆

Posted

技术标签:

【中文标题】如何在swift中从第一象限分割一个圆【英文标题】:How to segment a circle from first quadrant in swift 【发布时间】:2016-11-20 02:17:46 【问题描述】:

基本上我想创建一个计时器应用程序。这就是为什么我需要一个圆圈来显示计时器的进度。如果计时器为 10 秒,则圆圈将被分成 10 段,每段将在 1 秒后出现。好的。

我已经从SO post -> draw-a-circular-segment-progress-in-swift 成功创建了它,但是有点问题。我的圈子从第四象限开始,但不是预期的。我想显示第一象限的部分。在这里,我为 8 个段创建了这个函数。

请提供可以动态使用的建议。

 func createCircle()

        let circlePath = UIBezierPath(arcCenter: CGPoint(x: view.frame.size.width/2,y: view.frame.size.height/2), radius: CGFloat(90), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)


        let segmentAngle: CGFloat = (360 * 0.125) / 360

        for i in 0 ..< 8 

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

            // start angle is number of segments * the segment angle
            circleLayer.strokeStart = segmentAngle * CGFloat(i) //I think all is for this line of code.

            print("\nStroke \(i): ",segmentAngle * CGFloat(i))

            // end angle is the start plus one segment, minus a little to make a gap
            // you'll have to play with this value to get it to look right at the size you need
            let gapSize: CGFloat = 0.008

            circleLayer.strokeEnd = circleLayer.strokeStart + segmentAngle - gapSize

            circleLayer.lineWidth = 10

            circleLayer.strokeColor = UIColor(red:0,  green:0.004,  blue:0.549, alpha:1).CGColor
            circleLayer.fillColor = UIColor.clearColor().CGColor

            // add the segment to the segments array and to the view
            segments.insert(circleLayer, atIndex: i)

        

        for i in 0 ..< 8
            view.layer.addSublayer(segments[i])
        
    

【问题讨论】:

【参考方案1】:

你必须偏移你的起始角度:

circleLayer.strokeStart = segmentAngle * CGFloat(i) - M_PI / 2.0

虽然转换也可以解决问题,但我不建议在这种情况下使用转换。如果您稍后出于其他原因(动画等)想要进行转换,那么您可能还必须考虑任何当前的转换,这可能会使事情变得更加复杂。

编辑:

我认为您的其他一些代码也可能已关闭。我没有弄清楚发生了什么,而是从头开始重写它(使用 Swift 3 语法):

let count: Int = 8
let gapSize: CGFloat = 0.008
let segmentAngleSize: CGFloat = (2.0 * CGFloat(M_PI) - CGFloat(count) * gapSize) / CGFloat(count)
let center = CGPoint(x: view.frame.size.width / 2.0, y: view.frame.size.height / 2.0)
let radius: CGFloat = 90
let lineWidth: CGFloat = 10
let strokeColor = UIColor(red:0,  green:0.004,  blue:0.549, alpha:1).cgColor

for i in 0 ..< count 
    let start = CGFloat(i) * (segmentAngleSize + gapSize) - CGFloat(M_PI / 2.0)
    let end = start + segmentAngleSize
    let segmentPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: start, endAngle: end, clockwise: true)

    let arcLayer = CAShapeLayer()
    arcLayer.path = segmentPath.cgPath
    arcLayer.fillColor = UIColor.clear.cgColor
    arcLayer.strokeColor = strokeColor
    arcLayer.lineWidth = lineWidth

    self.view.layer.addSublayer(arcLayer)

【讨论】:

我使用了您的线路,但没有段。所以我打印了你的值,它显示为负值,但值为 [0,1] .....这就是它不起作用的原因。【参考方案2】:

基于@Jake 答案的 Swift 4 版本。

class SegmentView: UIView 
    @IBInspectable var segmentNumber: Int = 1
    @IBInspectable var lineWidth: CGFloat = 10.0
    @IBInspectable var strokeColor: UIColor = .red

    var gapSize: CGFloat = 0.07
    override func draw(_ rect: CGRect) 
        super.draw(rect)
        let segmentAngleSize: CGFloat = (2.0 * CGFloat.pi - CGFloat(segmentNumber) * gapSize) / CGFloat(segmentNumber)
        let center = CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0)

        for i in 0..<segmentNumber 
            let start = CGFloat(i) * (segmentAngleSize + gapSize) - .pi / 2.0
            let end = start + segmentAngleSize
            let segmentPath = UIBezierPath(arcCenter: center, radius: self.frame.width / 2 - lineWidth / 2, startAngle: start, endAngle: end, clockwise: true)

            let arcLayer = CAShapeLayer()
            arcLayer.path = segmentPath.cgPath
            arcLayer.fillColor = UIColor.clear.cgColor
            arcLayer.strokeColor = strokeColor.cgColor
            arcLayer.lineWidth = lineWidth

            layer.addSublayer(arcLayer)
        

    

【讨论】:

【参考方案3】:

使用旋转变换来旋转视图/图层,使形状图层路径的零点位于您想要的位置。

【讨论】:

github.com/mattneub/Programming-ios-Book-Examples/blob/master/…

以上是关于如何在swift中从第一象限分割一个圆的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中从服务器下载 zip 文件?

在SVG中从另一个圆中减去一个圆

如何在 Swift 中从数组中删除一个元素

如何在 Swift 中从 Firebase 接收数组

如何在 Swift 中从 Facebook 获取用户名

如何在 swift 中从 nsimage 创建灰度图像?