我不明白为什么 CAShapeLayer 不响应 hitTest
这个函数总是去 // touches is outside
如何检测 CAShapeLayer 上的触摸?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)事件 { currentPoint = [[touches anyObject] locationInView:self]; for (CAShapeLayer *layer in self.layer.sublayers) { 如果(层== shapeLayer){ if([层 hitTest:currentPoint]) { // touche 在图层上 } 别的 { // 触摸在外面 } } } }
苦思冥想两天后,我能够生成这个奇怪的代码,看起来它可以正常工作!
目标是命中测试 CAShapeLayer。 CAShapeLayer 在屏幕上移动,因此形状不在固定位置。命中 CGPath currentPoint 并不简单。
随意添加任何输入...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)事件 { CGPoint p = [[touches anyObject] locationInView:self]; CGAffineTransform transf = CGAffineTransformMakeTranslation(-shapeLayer.position.x, -shapeLayer.position.y); if(CGPathContainsPoint(shapeLayer.path, &transf, p, NO)){ // 触摸在形状内部 } }
见下文——覆盖 CAShapeLayers hitTest() 方法
// CAShapeLayer path coordinates are relative to the layer
// so when hit testing to see if the mouse click is inside the path
// convert the point to layer coordinates like so
// This assumes the received coordinates are in the layers superlayer coordinates
// Usually so if they come from a mouse click
override func hitTest(_ p: CGPoint) -> CALayer? {
let lp = self.convert(p, from: superlayer)
let result = path?.contains(lp) ?? false
return result ? self : nil
}
在您的 CAShapeLayer 子类中,您可以覆盖 contains(point:) 方法而不是覆盖 hitTest:
override func contains(_ p: CGPoint) -> Bool {
let result = self.path?.contains(p) ?? false
return result
}