绘制的圆圈不对齐

时间:2018-05-16 00:51:23

标签: ios swift

我正在尝试绘制钟面uiview并引用this example

我已经能够成功地绘制包括股票标记的基圆,但是,看起来重叠的圆在x轴上未对齐,其中自动收报机圈在基圆的右边突出。我的困惑在于,圆圈共享相同的x / y中心坐标,但我确实丢失了..

以下是参考代码......

class ClockView: UIView {

override func draw(_ rect:CGRect)

{
    let ctx = UIGraphicsGetCurrentContext()

    let rad = rect.width / 4

    let endAngle = CGFloat.pi * 2

    ctx?.addArc(center: CGPoint(x: rect.midY, y: rect.midY), radius: rad, startAngle: 0, endAngle: endAngle, clockwise: true)

    ctx?.setFillColor(UIColor.gray.cgColor)

    ctx?.setStrokeColor(UIColor.white.cgColor)

    ctx?.setLineWidth(4.0)

    ctx?.drawPath(using: .fillStroke)

    secondMarkers(ctx!, rect.midX, rect.midY, rad, 48, UIColor.white)
}

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

func secondMarkers(_ ctx: CGContext,_ x: CGFloat,_ y: CGFloat,_ radius: CGFloat,_ tickCount: Int,_ color: UIColor) {
    let points = circleCircumferencePoints(tickCount,x,y,radius)

    var divider: CGFloat = 1/8
    var counter = 0
    for p in points {
        if counter % 4 == 0 {
            divider = 1/4
        }
        else {
            divider = 1/8
        }

        let xn = p.x + divider*(x-p.x)
        let yn = p.y + divider*(y-p.y)

        let path = CGMutablePath()
        path.move(to: CGPoint(x: p.x, y: p.y))
        path.addLine(to: CGPoint(x: xn, y: yn))
        path.closeSubpath()

        ctx.addPath(path)
        counter += 1
    }

    let cgcolor = color.cgColor
    ctx.setStrokeColor(cgcolor)
    ctx.setLineWidth(3.0)
    ctx.strokePath()
}

func circleCircumferencePoints(_ tickCount:Int,_ x:CGFloat,_ y:CGFloat,_ radius:CGFloat,_ adjustment:CGFloat=0)->[CGPoint] {
    let angle = degree2Radian(a: 360/CGFloat(tickCount))
    let cx = x
    let cy = y
    let r  = radius
    var i = tickCount
    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
}
}

1 个答案:

答案 0 :(得分:2)

我使用此视图在Playground中尝试了您的代码:

let clock = ClockView(frame: CGRect(x: 0, y: 0, width: 500, height: 400))

结果是:

clock in Playground

你的问题就在这一行:

ctx?.addArc(center: CGPoint(x: rect.midY, y: rect.midY), radius: rad, startAngle: 0, endAngle: endAngle, clockwise: true)

您使用rect.midY作为视图的水平中心,我认为您的视图不是正方形。将其更改为rect.midX

ctx?.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rad, startAngle: 0, endAngle: endAngle, clockwise: true)

其他问题:

  1. sides未定义。我只需将其设置为60即可进行编译。
  2. 您的秒数值为48,一小时内有60

    变化:

    secondMarkers(ctx!, rect.midX, rect.midY, rad, 48, UIColor.white)
    

    为:

    secondMarkers(ctx!, rect.midX, rect.midY, rad, 60, UIColor.white)
    
  3. 5个刻度需要一个较长的分隔线,而不是4

    变化:

    if counter % 4 == 0 {
    

    为:

    if counter % 5 == 0 {
    
  4. 根据建议的更改,结果现在是:

    clock after

    以下是完整的代码:

    class ClockView: UIView {
    
        let sides = 60
    
        override func draw(_ rect:CGRect)
    
        {
            let ctx = UIGraphicsGetCurrentContext()
    
            let rad = rect.width / 4
    
            let endAngle = CGFloat.pi * 2
    
            ctx?.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rad, startAngle: 0, endAngle: endAngle, clockwise: true)
    
            ctx?.setFillColor(UIColor.gray.cgColor)
    
            ctx?.setStrokeColor(UIColor.white.cgColor)
    
            ctx?.setLineWidth(4.0)
    
            ctx?.drawPath(using: .fillStroke)
    
            secondMarkers(ctx!, rect.midX, rect.midY, rad, 60, UIColor.white)
        }
    
        func degree2Radian(a:CGFloat)-> CGFloat {
            let b = CGFloat.pi * a/180
            return b
        }
    
        func secondMarkers(_ ctx: CGContext,_ x: CGFloat,_ y: CGFloat,_ radius: CGFloat,_ tickCount: Int,_ color: UIColor) {
            let points = circleCircumferencePoints(tickCount,x,y,radius)
    
            var divider: CGFloat = 1/8
            var counter = 0
            for p in points {
                if counter % 5 == 0 {
                    divider = 1/4
                }
                else {
                    divider = 1/8
                }
    
                let xn = p.x + divider*(x-p.x)
                let yn = p.y + divider*(y-p.y)
    
                let path = CGMutablePath()
                path.move(to: CGPoint(x: p.x, y: p.y))
                path.addLine(to: CGPoint(x: xn, y: yn))
                path.closeSubpath()
    
                ctx.addPath(path)
                counter += 1
            }
    
            let cgcolor = color.cgColor
            ctx.setStrokeColor(cgcolor)
            ctx.setLineWidth(3.0)
            ctx.strokePath()
        }
    
        func circleCircumferencePoints(_ tickCount:Int,_ x:CGFloat,_ y:CGFloat,_ radius:CGFloat,_ adjustment:CGFloat=0)->[CGPoint] {
            let angle = degree2Radian(a: 360/CGFloat(tickCount))
            let cx = x
            let cy = y
            let r  = radius
            var i = tickCount
            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
        }
    }
    
    let clock = ClockView(frame: CGRect(x: 0, y: 0, width: 500, height: 400))