如何不允许圆形 UIView 识别其圆形边界之外的触摸?

How to not allow a circular UIView to recognize touches outside of it's circular bounds?

我有两个视图相互堆叠。假设视图 B 堆叠在较大视图 A 的顶部。视图 B 是圆形的,不应接受圆外的触摸,而较大的视图 A 应该接受触摸。

我尝试重写视图 B 的自定义 PanGesture 识别器的 touchesBegan 方法,以检查它是否在循环路径中,然后调用超级识别器上的 touches canceled,如下所示:

override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
    let touch = touches.anyObject() as UITouch
    let location = touch.locationInView(self.view)
    let isInPath = self.path.containsPoint(location)

    if(isInPath){
        super.touchesBegan(touches, withEvent: event)
        self.rotation = rotationForLocation(location)
    }else{
        // touch started outside of path so cancel touch
        super.cancelsTouchesInView = true
        super.touchesCancelled(touches, withEvent: event)
    }
}

它阻止视图B接受圆形路径外的触摸,但视图A不接受触摸。任何帮助将不胜感激,谢谢。

不要取消触摸,而是将它们转发给 A 对象。

您可以添加两个手势识别器,其中一个将指定一个具有 gestureRecognizerShouldBegin 方法的委托,只有在圆圈内时才会启动手势。只有当圆形手势失败时,您才能让非圆形手势成功。

// add square view

let subview = UIView(frame: frame)
subview.backgroundColor = UIColor.lightGrayColor()
subview.userInteractionEnabled = true
view.addSubview(subview)

// add circular shapelayer (so I can see the circle)

let circularShapeLayer = CAShapeLayer()
circularShapeLayer.frame = subview.bounds
circularShapeLayer.path = UIBezierPath(ovalInRect: subview.bounds).CGPath
circularShapeLayer.fillColor = UIColor.darkGrayColor().CGColor
subview.layer.addSublayer(circularShapeLayer)

// add gesture that will use delegate method `gestureRecognizerShouldBegin` to determine if you started in the circle

let circlePanGesture = UIPanGestureRecognizer(target: self, action: "handleCircularPan:")
circlePanGesture.delegate = self
subview.addGestureRecognizer(circlePanGesture)

// add a gesture recognizer that will only be recognized if the prior gesture recognizer fails

let squarePanGesture = UIPanGestureRecognizer(target: self, action: "handleSquarePan:")
squarePanGesture.requireGestureRecognizerToFail(circlePanGesture)
subview.addGestureRecognizer(squarePanGesture)

委托方法可能如下所示:

func gestureRecognizerShouldBegin(gesture: UIGestureRecognizer) -> Bool {
    let center = CGPoint(x: gesture.view!.bounds.size.width / 2.0, y: gesture.view!.bounds.size.height / 2.0)
    let location = gesture.locationInView(gesture.view)
    let distance = hypot(center.x - location.x, center.y - location.y)
    return distance < (gesture.view!.bounds.size.width / 2.0)
}

请注意,我将这两个手势添加到同一个子视图(因为如果我有重叠视图,两个视图都有 userInteractionEnabled,如果获得手势,则只有最上面的一个)。