如何使用UIKit绘制一个看起来像钟面的圆形图

时间:2016-11-28 06:56:48

标签: ios iphone swift xcode

我一直试图解决这个问题太久了。在this blog 的帮助下,我设法绘制了图表本身,但它无法向我显示任何数据,因为看起来我创建上下文数组的想法是不可能的,我只能有一个上下文每个观点,是吗?那么如何单独更改每个标记的颜色呢?我已经看过使用SpriteKit的解决方案,但我对SpriteKit一无所知。

func degree2Radian(a:CGFloat)->CGFloat {
    let b = CGFloat(M_PI) * a/180
    return b
}

override func draw(_ rect: CGRect) {
    color.set()
    pathForCircleCenteredAtPoint(midPoint: circleCenter, withRadius: circleRadius).stroke()
    color = UIColor.white
    color.set()
    pathForCircleCenteredAtPoint(midPoint: CGPoint(x: bounds.midX, y: bounds.midY), withRadius: circleRadius).fill()
    color = UIColor(red: 0.93, green: 0.93, blue: 0.94, alpha: 1)
    color.set()
    let ctx = UIGraphicsGetCurrentContext()
    for i in 0...100 {
        secondMarkers(ctx: ctx!, x: circleCenter.x, y: circleCenter.y, radius: circleRadius - 4, sides: 100, color: color)
    }
    diagramArray[0].strokePath()
}

func degree2radian(a:CGFloat)->CGFloat {
    let b = CGFloat(M_PI) * a/180
    return b
}

func circleCircumferencePoints(sides:Int,x:CGFloat,y:CGFloat,radius:CGFloat,adjustment:CGFloat=0)->[CGPoint] {
    let angle = degree2radian(a: 360/CGFloat(sides))
    let cx = x // x origin
    let cy = y // y origin
    let r  = radius // radius of circle
    var i = sides
    var points = [CGPoint]()
    while points.count <= sides {
        let xpo = cx - r * cos(angle * CGFloat(i)+degree2radian(a: adjustment))
        let ypo = cy - r * sin(angle * CGFloat(i)+degree2radian(a: adjustment))
        points.append(CGPoint(x: xpo, y: ypo))
        i -= 1;
    }
    return points
}

func secondMarkers(ctx:CGContext, x:CGFloat, y:CGFloat, radius:CGFloat, sides:Int, color:UIColor) {
    // retrieve points
    let points = circleCircumferencePoints(sides: sides,x: x,y: y,radius: radius)
    // create path

    // determine length of marker as a fraction of the total radius
    var divider:CGFloat = 1/16
    //for p in points {
        let path = CGMutablePath()
        divider = 1/10

        let xn = points[counter].x + divider * (x-points[counter].x)
        let yn = points[counter].y + divider * (y-points[counter].y)
        // build path
        path.move(to: CGPoint(x: points[counter].x, y: points[counter].y))
        //path, nil, p.x, p.y)
        path.addLine(to: CGPoint(x: xn, y: yn))
        //CGPathAddLineToPoint(path, nil, xn, yn)
        path.closeSubpath()
        // add path to context
        ctx.addPath(path)
        ctx.setStrokeColor(color.cgColor)
        ctx.setLineWidth(2.0)
        //ctx.strokePath()
        diagramArray.append(ctx)
        counter += 1
    //}
    // set path color
}

所以基本上我试图将每个标记的上下文追加到一个数组,但是当我绘制这个数组的一个元素时,它会绘制整个图。 This is what I need to achieve

1 个答案:

答案 0 :(得分:1)

您不需要创建多个CGContext - 您应该重复使用同一个来绘制所有图形。此外,您计算secondMarkers的方法似乎不必要地复杂。我相信这可以做你想要的:

private func drawTicks(context: CGContext, tickCount: Int, center: CGPoint, startRadius: CGFloat, endRadius: CGFloat, ticksToColor: Int) {
  for i in 0 ... tickCount {
    let color: UIColor = i < ticksToColor ? .blue : .lightGray
    context.setStrokeColor(color.cgColor)
    let angle = .pi - degree2Radian(a: (CGFloat(360.0) / CGFloat(tickCount)) * CGFloat(i))
    let path = CGMutablePath()
    path.move(to: circleCircumferencePoint(center: center, angle: angle, radius: startRadius))
    path.addLine(to: circleCircumferencePoint(center: center, angle: angle, radius: endRadius))
    context.addPath(path)
    context.strokePath()
  }
}


private func circleCircumferencePoint(center: CGPoint, angle: CGFloat, radius: CGFloat) -> CGPoint {
  return CGPoint(x: radius * sin(angle) + center.x, y: radius * cos(angle) + center.y)
}