如何不允许圆形 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
,如果获得手势,则只有最上面的一个)。
我有两个视图相互堆叠。假设视图 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
,如果获得手势,则只有最上面的一个)。