围绕一圈

时间:2017-01-19 14:24:12

标签: ios swift geometry core-graphics

enter image description here

我正在尝试创建一个自动旋钮控件,其表盘周围有刻度。表盘将有一个动态的刻度(值),所以我需要绘制它们。首先,我要做的就是创建一个圆圈,边缘周围有许多刻度线。上面是一个示例图像。

这是我目前所处的位置(下图),你可以看到我的数学必须完全关闭,而且我很难让它正确显示。角度看起来相距很远,蜱的位置应该是向右的1/2和向下的1/2。我尝试使用ShapeLayer并移动它,但它似乎没有做任何事情。一旦我得到正确的图纸,我会把它做得更大,使它看起来像顶部的图像(被屏幕边界剪切)。

此时我真正想做的是在圆圈边缘绘制动态数量的抽搐。它们之间的角度确实也可以固定。感谢您的时间和关注。

enter image description here

这是我目前的自定义课程。

import UIKit

class Disc: UIView {

// Defaults.
private var myOuterRadius: CGFloat = 100.0
private var myInnerRadius: CGFloat = 90.0
private var myNumberOfTicks: Int = 5

override func draw(_ rect: CGRect)
{
    let strokeColor = UIColor.black
    let tickPath = UIBezierPath()
    for i in 0..<myNumberOfTicks {
        let angle = CGFloat(i) * CGFloat(2 * M_PI) / CGFloat(myNumberOfTicks)
        let inner = CGPoint(x: myInnerRadius * cos(angle), y: myInnerRadius * sin(angle))
        let outer = CGPoint(x: myOuterRadius * cos(angle), y: myOuterRadius * sin(angle))
        print(angle, inner, outer)
        tickPath.move(to: inner)
        tickPath.addLine(to: outer)
    }
    tickPath.close()
    tickPath.lineCapStyle = .round
    strokeColor.setStroke()
    tickPath.lineWidth = 2
    tickPath.stroke()
}

init(width: CGFloat, numTicks: Int)
{
    super.init(frame: CGRect(x: 0, y: 0, width: width, height: width))

    myOuterRadius = width / 2
    myInnerRadius = (width / 2) - 10
    myNumberOfTicks = numTicks

    self.backgroundColor = UIColor(netHex: 0xEEEEEE)
    self.layer.cornerRadius = CGFloat(width / 2)
    self.layer.masksToBounds = true
}

required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}

3 个答案:

答案 0 :(得分:1)

您的问题是您使用(0, 0)作为圈子的中心。

您需要为圆的中心点建立值,然后将这些偏移添加到刻度线的端点。

let centerX: CGFloat = myOuterRadius
let centerY: CGFloat = myOuterRadius

然后在计算innerouter时使用这些值:

let inner = CGPoint(x: myInnerRadius * cos(angle) + centerX,
    y: myInnerRadius * sin(angle) + centerY)
let outer = CGPoint(x: myOuterRadius * cos(angle) + centerX,
    y: myOuterRadius * sin(angle) + centerY)

答案 1 :(得分:1)

正如vacawama所指出的,你必须在计算中添加圆心的位置。您只需使用UIView的{​​{3}}属性即可。

let inner = CGPoint(x: myInnerRadius * cos(angle) + center.x, 
                    y: myInnerRadius * sin(angle) + center.y)
let outer = CGPoint(x: myOuterRadius * cos(angle) + center.x, 
                    y: myOuterRadius * sin(angle) + center.y)

答案 2 :(得分:1)

这将是一个良好的开端。当然还有更好的方法。 :P

class ViewController: UIViewController {

var circle: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    let diameter = 200.0
    let ticks = 100

    circle = UIView(frame: CGRect(x: 0, y: 0, width: diameter, height: diameter))
    circle.center = view.center
    circle.backgroundColor = UIColor.yellow
    circle.layer.cornerRadius = 100.0
    view.addSubview(circle)

    drawTicks(count: ticks)
}

func drawTicks(count: Int) {

    let radius = circle.frame.size.width * 0.5
    var rotationInDegrees: CGFloat = 0

    for i in 0 ..< count {
        let tick = createTick()

        let x = CGFloat(Float(circle.center.x) + Float(radius) * cosf(2 * Float(i) * Float(M_PI) / Float(count) - Float(M_PI) / 2))
        let y = CGFloat(Float(circle.center.y) + Float(radius) * sinf(2 * Float(i) * Float(M_PI) / Float(count) - Float(M_PI) / 2))

        tick.center = CGPoint(x: x, y: y)
        // degress -> radians
        tick.transform = CGAffineTransform.identity.rotated(by: rotationInDegrees * .pi / 180.0)
        view.addSubview(tick)

        rotationInDegrees = rotationInDegrees + (360.0 / CGFloat(count))
    }

}

func createTick() -> UIView {
    let tick = UIView(frame: CGRect(x: 0, y: 0, width: 2.0, height: 10.0))
    tick.backgroundColor = UIColor.blue

    return tick
}

}

Result