我想显示很多星星,当用户触摸其中一颗星星的内部时,我可以改变星星的颜色,并将星星id附加到数组中。
我有一个恒星坐标数组=[[恒星1的顶点坐标],[恒星2的顶点坐标],...,[恒星60的顶点坐标]]
//function to create a star UIBezierPath
func StarFromArray(points: [Array<Int>] ) -> UIBezierPath {
let starPath = UIBezierPath()
let point1 = points[0]
starPath.move(to: CGPoint(x: point1[0], y: point1[1]))
for i in 1...(starPath.count-1) {
let ar = starPath[i]
starPath.addLine(to: CGPoint(x: ar[0], y: ar[1]))
}
starPath.close()
return starPath
}
//function to create and display every star from my StarArray, I call this in ViewDidLoad
func loadStar() {
for i in 0...StarArray.size {
let ar = StarArray[i]
let starLayer = CAShapeLayer()
let star = StarFromArray(points: ar)
starLayer.path = star.cgPath
starLayer.fillColor = UIColor.blue.cgColor
self.view.layer.addSublayer(starLayer)
}
}
上面的代码显示了我所有的星星,现在我需要为我的每个星星创建一个触摸事件,这样当一个星星被触摸时,我可以将一个星星ID追加到一个数组中。
我该怎么做?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let point = touch!.location(in: self.view)
if starLayer.path!.contains(point) {
print("star touched")
starLayer.fillColor = UIColor.blue.cgColor
}
}
上面的代码是如果我有一颗星的话可以使用的,但是如果我有很多颗星的话显然就不起作用了。
不能将触摸事件发送到图层。你得自己处理。我建议在包含这些图层的视图上附加一个手势识别器,然后为每个图层添加一个包含边界矩形的结构数组,然后确定哪一个图层是这样点击的。
CALayer确实有一个最棒的方法,你可以用它来判断一个轻击是否落在一个图层中,但你必须自己来决定它。您可以在父层上调用hittest()
,它会告诉您点击落在哪个子层(或父层)的帧上。
如果您想要检测不规则形状(如您的星型示例图像)内的抽头,您必须自己编写代码。(UIBezierPath和CGPath都有contains()
方法,您可以使用这些方法查询路径,以查看某个点是否位于路径内部。)