圆形视图上的手势识别器

Posted

技术标签:

【中文标题】圆形视图上的手势识别器【英文标题】:Gesture recognizer on a circular view 【发布时间】:2016-10-15 19:48:41 【问题描述】:

在我的集合视图的每个单元格中都有一个圆形 UIView。这是通过创建UIView 的自定义子类(我称之为CircleView)并在子类'awakeFromNib() 中设置layer.cornerRadius = self.frame.size.width/2 来实现的

我想为每个 CircleView 添加一个手势识别器。我在集合视图的cellForItemAtIndexPath 中完成了此操作:

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tap(_:)))
cell.circleView.addGestureRecognizer(gestureRecognizer)

问题在于,只要在原始方形 UIView 的边界内的任何地方发生点击,就会调用手势识别器。我只想识别圈内发生的点击。

我已尝试通过以下方式解决此问题:

在CircleView的awakeFromNib()我设置了self.clipsToBounds = true(没有效果)

也在CircleView的awakeFromNib()我设置了layer.masksToBounds = true(没有效果)

提前感谢您的想法和建议。

【问题讨论】:

您是否使用建议的解决方案解决了您的问题? cellForItemAtIndexPath 中添加UITapGestureRecognizer 的新实例并不是最好的主意。当您滚动此集合视图时,这将一遍又一遍地添加重复的识别器,因为单元格被重复使用。 【参考方案1】:

您可以在 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)

所有不属于圆圈的触摸都将被忽略。

更多详情:

https://developer.apple.com/reference/uikit/uiview/1622469-hittest https://developer.apple.com/reference/uikit/uiview/1622533-point

主要的一点是你不需要调用hitTestpointInside 方法,你只需在你的自定义视图中覆盖它们,系统会在需要知道是否应该处理触摸时调用它们这个观点。

在您的情况下,您有一个 UITableViewCell 和一个 CircleView,对吧?您已将手势识别器添加到 CircleView 并覆盖 pointInside 方法,因此如果触摸点位于圆圈内,则触摸将由 CircleView 本身处理,否则将进一步传递事件,由单元格处理,因此didSelectRowAtIndexPath 将被调用。

【讨论】:

感谢您的回答。我已将此功能添加到 CircleView,但不确定如何使用它。我尝试了两种方法。 1) 使用let tapLocation = gestureRecognizer.location(in: self.view) 获取水龙头的位置。但是现在我不知道如何将它传递给函数来检查它是否在圆圈内。 2)我可以使用集合视图的didSelectItemAtIndexPath,在这里我可以使用cell.circleView.point访问该功能,但是使用此选项我不明白如何获取要传递的水龙头的位置。 顺便说一下,图片对于理解如何代码的工作方式很有帮助。谢谢!我只是不知道如何将它与手势识别器(或集合视图的 didSelectItemAtIndexPath.. 都可以!) @AustinWood 您不应该使用这种方法手动传递水龙头的位置。如果您覆盖pointInside 方法,它将在需要时自动调用。查看更新的答案。 啊,现在我明白了。谢谢你。在您提供的代码中,我认为应该是let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2)。在您的版本中,中心坐标不除以 2。我将其更改为这个,现在它适用于我。 @AustinWood 是的,这是我答案的第一个版本中的一个错误,我在 10 分钟后修复了它:) 很高兴它有帮助。

以上是关于圆形视图上的手势识别器的主要内容,如果未能解决你的问题,请参考以下文章

将平移手势识别器限制为特定圆圈

如何在弹出视图上识别手势而不中断下方视图上的手势识别?

UITableViewCell 上的 UIPanGestureRecognizer 覆盖 UITableView 的滚动视图手势识别器

ios 滑动手势在子视图上未被识别,父视图上的手势

iOS - 使用/传递手势识别器用于视图中的多个表视图或集合视图(Swift)

表格视图单元格中 UIView 上的手势识别器