抓紧,这涉及到一些数学!
假设圆的中心是(0,0)。假设你有一个点(x,y)位于圆周上,你可以使用
atan2 or arctan2 function
得到角度(弧度;
弧度是你想要的
UIBezierPath
使用弧度
)点位于圆的中心。所以,有了这个角度,你就知道用户在你的圆周长上触到了什么地方(称之为
touch angle
)你可以用这个作为你的
endAngle
在
小精灵
.
注:
如果圆的中心不是(0,0),而是(x1,y1),则通过减去接触点(x,y)的差来补偿,即,新点是(x-x1,y-y1)
如果你想要一个0 rads的周长的百分比。你可以用公式
percentage = (touch angle*(in rads)* * 100)/2Ï)
.
关于atan2/arctan2的更多信息
你可以用公式计算你的触角
touch angle = tan^(-1)(y/x)
阿卡
touch angle = arctan2(y,x)
. 在哪里?
(x,y)
是用户在圆周上接触的点。
举例说明
(编辑)
可以
呸
,经过一番研究,我想出来了。
拿一个
look at this code
注意
touchesBegan(_ ...
功能。
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
for touch in touches {
let point = touch.location(in: self)
if backCircleBezierPath!.contains(point) {
print("contains")
let centeredPoint = CGPoint(x: (point.x - frame.width/2), y: (point.y - frame.height/2))
print(centeredPoint)
var rads = atan(centeredPoint.y/centeredPoint.x)
if centeredPoint.x < 0 {
rads += CGFloat.pi
} else if centeredPoint.x > 0 && centeredPoint.y < 0 {
rads += CGFloat.pi * 2
}
let perc = (rads - backCircleStartAngle) / abs(backCircleStartAngle - backCircleEndAngle)
frontCircleShapeLayer?.strokeEnd = perc
}
}
}
我已经用过
CAShapeLayer
而不是拉进来
draw(_ rect...
;我建议你也这样做。你的方法也很好,但有一些变化,我将在最后提到。
我用了两个弧:
1。占位符弧-
backCircleShapeLayer
2。进度指示弧-
frontCircleShapeLayer
当用户点击占位符弧时,我们可以计算角度(以弧度为单位)并从
start Angle
到
touch Angle
如前所述(
使用此方法直接绘制笔划
小精灵
在
draw(_ ...
方法
,但我要做的是用这些值来计算分数
perc
(介于0和1之间)并将其用作
stroke end
进步的弧线。
这带来了一些有趣的新知识。价值
atan(y/x)
是特定于域的(
Some math behind this, if you're interested
)所以
如果您的触摸在第四象限,则添加360_或2_,如果在第二象限或第三象限,则添加180_或2_。
. 在这个添加之后
触角
应该体现出完美的价值。