Detecting a tap on a CAShapeLayer in Swift?

前端 未结 4 560
时光取名叫无心
时光取名叫无心 2020-12-29 13:18

I\'m quite new to iOS Development (so please forgive my ineptitude - I\'ve looked everywhere!), and was looking to find a way to detect a tap on a CAShapeLayer.

相关标签:
4条回答
  • 2020-12-29 13:43

    Use following code for get touch of CAShapeLayer.

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        for (UITouch *touch in touches) {
            CGPoint touchLocation = [touch locationInView:self.view];
            for (id sublayer in self.view.layer.sublayers) {
                BOOL touchInLayer = NO;
                if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
                    CAShapeLayer *shapeLayer = sublayer;
                    if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
                        // Here your code for do any opration.
                        touchInLayer = YES;
                    }
                } else {
                    CALayer *layer = sublayer;
                    if (CGRectContainsPoint(layer.frame, touchLocation)) {
                        // Touch is in this rectangular layer
                        touchInLayer = YES;
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-29 13:50

    Heres imo the best way to do what you want to achieve:

    // First add the shapelayer
    let layer = CAShapeLayer()
    layer.anchorPoint = CGPointZero
    layer.path = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 100, height: 200)).CGPath
    layer.bounds = CGPathGetBoundingBox(layer.path) // IMPORTANT, without this hitTest wont work
    layer.fillColor = UIColor.redColor().CGColor
    self.view.layer.addSublayer(layer)
    
    
    // Check for touches
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        let point = touches.anyObject()!.locationInView(self.view) // Where you pressed
    
        if let layer = self.view.layer.hitTest(point) as? CAShapeLayer { // If you hit a layer and if its a Shapelayer
            if CGPathContainsPoint(layer.path, nil, point, false) { // Optional, if you are inside its content path
                println("Hit shapeLayer") // Do something
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-29 14:04

    Swift 4 & 5

    My UIImageView has multiple embedded CAShapeLayer objects. Here is how I was able to detect taps on them. Referenced from this tutorial.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
    
        guard let point = touch?.location(in: imageView) else { return }
        guard let sublayers = imageView.layer.sublayers as? [CAShapeLayer] else { return }
    
        for layer in sublayers {
            if let path = layer.path, path.contains(point) {
                print(layer)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-29 14:05

    I used Arbitur's code and i had some errors. Here is a code i had with no errors. For swift 3.2 / 4.0

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let layer = CAShapeLayer()
        layer.anchorPoint = CGPoint.zero
        layer.path = UIBezierPath.init(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 200)).cgPath
        layer.bounds = (layer.path?.boundingBox)! // IMPORTANT, without this hitTest wont work
        layer.fillColor = UIColor.red.cgColor
        self.view.layer.addSublayer(layer)
    
    }
        // Check for touches
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let point = touches.first?.location(in: self.view) // Where you pressed
    
        if let layer = self.view.layer.hitTest(point!) as? CAShapeLayer { // If you hit a layer and if its a Shapelayer
            if (layer.path?.contains(point!))! { // Optional, if you are inside its content path
                print("Hit shapeLayer") // Do something
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题