简体   繁体   English

圆形视图上的手势识别器

[英]Gesture recognizer on a circular view

In each cell of my collection view is a circular UIView. 在我的集合视图的每个单元格中都有一个圆形的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() 这是通过创建UIView的自定义子类(我称为CircleView )并在子类的awakeFromNib()设置layer.cornerRadius = self.frame.size.width/2来实现的。

I want to add a gesture recognizer to each CircleView. 我想向每个CircleView添加一个手势识别器。 I have done this in the collection view's cellForItemAtIndexPath : 我已经在集合视图的cellForItemAtIndexPath完成了此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. 问题在于,只要在原始方形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) 在CircleView的awakeFromNib()我设置self.clipsToBounds = true (无效)

Also in the CircleView's awakeFromNib() I set layer.masksToBounds = true (no effect) 同样在CircleView的awakeFromNib()我设置layer.masksToBounds = true (无效)

Thank you in advance for your ideas and suggestions. 预先感谢您的想法和建议。

You can override this method in CircleView: 您可以在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 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. 要点是,您无需调用hitTestpointInside方法,只需在自定义视图中覆盖它们即可,并且只要需要知道此视图是否应该处理触摸,系统就会调用它们。

In your case you've got a UITableViewCell with a CircleView in it, right? 在您的情况下,您有一个带有CircleViewUITableViewCell ,对吗? 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. 您添加了一个手势识别来CircleView和被覆盖的pointInside方法,所以触摸会被处理CircleView本身,如果一个触摸点在圆圈内,否则事件将进一步通过,通过细胞进行处理,因此didSelectRowAtIndexPath将被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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