简体   繁体   中英

Gesture recognizer on a circular view

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM