首页 > 解决方案 > 创建许多 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
            
        }
    }

如果我有一颗星,我可以使用上面的代码,但如果我有很多星,显然它不起作用。

标签: iosswift

解决方案


您不能将触摸事件发送到图层。你需要自己管理。我建议在包含这些层的视图上附加一个手势识别器,然后为每一层添加一个包含边界矩形的结构数组,并找出以这种方式点击了哪个。

CALayer 确实有一个 hitTest 方法,您可以使用它来确定点击是否确实落在图层中,但您必须自己调用它。您可以调用hitTest()父层,它会告诉您点击落在哪个子层(或父层)的框架上。

如果您想检测星形示例图像等不规则形状内的点击,您必须自己编写该代码。(UIBezierPath 和 CGPath 都具有contains()可用于询问路径以查看点是否位于路径内部的方法。)


推荐阅读