ios - 创建许多 CAShapeLayer 并在其中创建 unqiue 触摸事件
问题描述
我想显示很多星星,当用户触摸其中一颗星星时,我可以更改星星的颜色并将星星 id 附加到数组中。
我有一个星坐标数组= [[star1的顶点坐标],[star2的顶点坐标],....,[star60的顶点坐标]]
//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 方法,您可以使用它来确定点击是否确实落在图层中,但您必须自己调用它。您可以调用hitTest()
父层,它会告诉您点击落在哪个子层(或父层)的框架上。
如果您想检测星形示例图像等不规则形状内的点击,您必须自己编写该代码。(UIBezierPath 和 CGPath 都具有contains()
可用于询问路径以查看点是否位于路径内部的方法。)
推荐阅读
- html - 输入 css“宽度 100%”大于容器的文本
- kotlin - 了解 Kotlin 中的二级构造函数
- javascript - 嵌套了几个三元运算符
- console - reCAPTCHA v3 管理控制台是否免费且无需 GSuite 帐户即可访问?如果有,在哪里?
- java - Spring 5 不可变形式在没有参数构造函数时使用全参数构造函数
- php - 如何正确迁移存储过程?
- jdbc - “ICMP 端口无法访问” - 无法通过 JDBC 连接到 HIVE db(使用 KERBEROS)
- vue.js - 在 Chrome Devtools 控制台中计算 Vue.js 状态对象的所有属性?
- python - 根据字典赋值
- python - 根据数组中值的索引选择系列值