【问题标题】:Detecting where a tap is made in CAShapeLayer检测在 CAShapeLayer 中点击的位置
【发布时间】:2015-11-25 15:45:59
【问题描述】:

我正在尝试实现一个需要对触摸做出反应的自定义图表。我正在使用CAShapeLayer 在视图控制器视图中绘制图形。代码如下:

var PILL_GRAPH_ENDING_X_AXIS    : CGFloat!
    var PILL_GRAPH_BEGINNING_X_AXIS : CGFloat!
    var PILL_GRAPH_DRAW_WIDTH       : CGFloat!
    var PILL_GRAPH_Y_AXIS           : CGFloat!

    var graphLayer                  : CAShapeLayer!
    var tapGestureRecognizer        : UITapGestureRecognizer!

    //MARK: View Management
    override func viewDidLoad() {
        super.viewDidLoad()
        tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "viewTapped:")
        view.addGestureRecognizer(tapGestureRecognizer)
    }
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        print("View will appear has been called")
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        print("View will layout subviews")
        PILL_GRAPH_Y_AXIS = view.frame.size.height/2
        PILL_GRAPH_DRAW_WIDTH = 80
        PILL_GRAPH_ENDING_X_AXIS = view.frame.size.width-50
        PILL_GRAPH_BEGINNING_X_AXIS = 50
        drawPillGraph()
    }

    //MARK: Graph Drawing

    func drawPillGraph() {
        let bezierPath = UIBezierPath()
        graphLayer = CAShapeLayer()
        //Prepare the line drawing
        bezierPath.moveToPoint(CGPoint(x: PILL_GRAPH_BEGINNING_X_AXIS, y: PILL_GRAPH_Y_AXIS))
        let endingPoint = CGPoint(x: PILL_GRAPH_ENDING_X_AXIS, y: PILL_GRAPH_Y_AXIS)
        bezierPath.addLineToPoint(endingPoint)
        graphLayer.opacity = 1.0
        graphLayer.backgroundColor = UIColor.lightGrayColor().CGColor
        graphLayer.strokeColor = UIColor.redColor().CGColor
        graphLayer.lineWidth = PILL_GRAPH_DRAW_WIDTH
        graphLayer.lineCap = kCALineCapRound
        graphLayer.path = bezierPath.CGPath
        view.layer.addSublayer(graphLayer)
    }

    func viewTapped(gestureRecognizer: UITapGestureRecognizer){
        print("View tapped")

        let touch = gestureRecognizer.locationInView(self.view)

    }

这将生成一个如下所示的图表:

我想要做的是能够检测何时点击红色图表以及点击点CGPoint,特别是在点击的图表中。我尝试了几种不同的方法来尝试使用hitTest:CGPointContainsPoint,但我一直无法成功实现我想要做的事情。如果有人有如何做到这一点的例子,将不胜感激。

【问题讨论】:

  • 实现 hitTest 方法是正确的解决方案。如果您的代码不起作用,请编辑您的问题以显示该代码,我们可以帮助您调试它。

标签: ios swift uiview uikit cashapelayer


【解决方案1】:

这是我直接从我的项目中复制的一些代码(CGPathContainsPoint 代码除外)。在我的例子中,手势识别器是长按,但这就是我实现hitTest:

的方式
func didLongPressView(lpGesture:UILongPressGestureRecognizer) {
    let location = lpGesture.locationInView(self)
    let point = self.convertPoint(location, fromView: nil)

    let foundLayer = self.rootLayer!.hitTest(point)

    if let shapeLayer = foundLayer as? CAShapeLayer {
        // You've found a shape layer, see if the point is inside
        // its path
        if CGPathContainsPoint(shapeLayer.path, nil, point, false) {
            // The tap was inside the shape layer's path.

        }

    }

}

rootLayer 变量是我的层层次结构中最外层(顶级父级)。

【讨论】:

    【解决方案2】:

    Swift 3.0 中,事情变得更加简洁和不同。

        func buttonTapped(sender: UITapGestureRecognizer) {
        // Check location of tap in the View.
        let location = tapGesture?.location(in: self.view)
        // Convert location into a Point
        let point = self.view.convert(location!, from: nil)
    
        if shapeLayer!.path!.contains(point) {
            startAnimation()
        }
    

    或者使用您的 LongPress 示例马特...

        func didLongPressView(sender: UILongPressGestureRecognizer) {
        // Check location of long press in the View.
        let location = lpGesture?.location(in: self.rootLayer)
        // Convert location into a Point
        let point = self.rootLayer.convert(location!, from: nil)
    
        if shapeLayer!.path!.contains(point) {
            startAnimation()
        }
    

    即在此函数之外声明的 tapGesture/lpGesture 并且 ShapeLayer 已在 viewDidLoad 中实例化为 CAShapeLayer()(如下所示)......

        self.shapeLayer = CAShapeLayer()
        shapeLayer!.path = shapeBezier.cgPath
        shapeLayer!.fillColor = UIColor.whiteColor().cgColor
        self.view.layer.addSublayer(shapeLayer!)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      相关资源
      最近更新 更多