在Swift中检测CAShapeLayer上的点击?

时间:2015-04-21 13:09:14

标签: ios swift cashapelayer

我对iOS开发很新(所以请原谅我的无能 - 我到处寻找!),并且正在寻找一种方法来检测CAShapeLayer上的点击。到目前为止,我遇到了hitTesthitTest是最好的方法,如果是这样,它在Swift中的使用方式尤其是CAShapeLayer s?另外,如果我有很多CAShapeLayers,我如何使用hitTest方法单独引用它们?

这就是我创建CAShapeLayer的方式:

    let newBounds = CGRect(x: 0, y: 0, width: 200, height: 200)
    let newShape = CAShapeLayer()
    newShape.bounds = newBounds
    newShape.position = view.center
    newShape.cornerRadius = newBounds.width / 2
    newShape.path = UIBezierPath(ovalInRect: newShape.bounds).CGPath

    newShape.lineWidth = 42
    newShape.strokeColor = UIColor(red: 222/255.0, green: 171/255.0, blue: 66/255.0, alpha: 1.0).CGColor
    newShape.fillColor = UIColor.clearColor().CGColor

    newShape.strokeStart = 0.2
    newShape.strokeEnd = 0.4

    view.layer.addSublayer(newShape)

4 个答案:

答案 0 :(得分:9)

这是实现你想要实现目标的最好方式:

// 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
        }
    }
}

答案 1 :(得分:6)

Swift 4

我的UIImageView有多个CAShapeLayer个对象,以下是我能够检测到它们的方法。

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)
            }
        }
    }

Ref

答案 2 :(得分:2)

我使用了Arbitur的代码,但我遇到了一些错误。 这是我没有错误的代码。对于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
        }
    }
}

答案 3 :(得分:0)

使用以下代码获取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;
                }
            }
        }
    }
}