Reputation: 378
In each cell of my collection view is a circular UIView. This has been achieved by creating a custom subclass of UIView
, which I have called CircleView
, and setting layer.cornerRadius = self.frame.size.width/2
in the subclass' awakeFromNib()
I want to add a gesture recognizer to each CircleView. I have done this in the collection view's cellForItemAtIndexPath
:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tap(_:)))
cell.circleView.addGestureRecognizer(gestureRecognizer)
The problem is that the gesture recognizer is called whenever a tap occurs anywhere within the bounds of the original square UIView. I want to only recognize taps that occur within the circle.
I have tried to solve this issue in the following ways:
In the CircleView's awakeFromNib()
I set self.clipsToBounds = true
(no effect)
Also in the CircleView's awakeFromNib()
I set layer.masksToBounds = true
(no effect)
Thank you in advance for your ideas and suggestions.
Upvotes: 3
Views: 1054
Reputation: 7741
You can override this method in CircleView:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let center = CGPoint(x: bounds.size.width/2, y: bounds.size.height/2)
return pow(center.x-point.x, 2) + pow(center.y - point.y, 2) <= pow(bounds.size.width/2, 2)
}
All touches not belonging to the circle will be ignored.
More details:
https://developer.apple.com/reference/uikit/uiview/1622469-hittest https://developer.apple.com/reference/uikit/uiview/1622533-point
The main point is that you don't need to call neither hitTest
nor pointInside
methods, you just override them in your custom view and system will call them whenever it needs to know if a touch should be handled by this view.
In your case you've got a UITableViewCell
with a CircleView
in it, right? You've added a gesture recognizer to CircleView
and overriden pointInside
method, so a touch will be handled by CircleView
itself if a touch point is inside the circle, otherwise event will be passed further, handled by cell and therefore didSelectRowAtIndexPath
will be called.
Upvotes: 12