我正在尝试绘制钟面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
}
}
答案 0 :(得分:2)
我使用此视图在Playground中尝试了您的代码:
let clock = ClockView(frame: CGRect(x: 0, y: 0, width: 500, height: 400))
结果是:
你的问题就在这一行:
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)
其他问题:
sides
未定义。我只需将其设置为60
即可进行编译。您的秒数值为48
,一小时内有60
。
变化:
secondMarkers(ctx!, rect.midX, rect.midY, rad, 48, UIColor.white)
为:
secondMarkers(ctx!, rect.midX, rect.midY, rad, 60, UIColor.white)
每5
个刻度需要一个较长的分隔线,而不是4
。
变化:
if counter % 4 == 0 {
为:
if counter % 5 == 0 {
根据建议的更改,结果现在是:
以下是完整的代码:
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))