ios - 改变 UICollectionViewCell 手势命中框的形状

标签 ios swift uigesturerecognizer uicollectionviewcell

我有一堆 UICollectionViewCells 看起来是圆形的(想象一个圆形的背景图像)。我想检测何时点击其中一个,但目前单元格的手势点击框是方形的,对应于单元格的高度和宽度。因此,点击正方形的一角(有点超出圆形外观)仍然被视为手势:

circle in square

我正在考虑一种方法来做到这一点,同时仍然能够使用 indexPathForItemAtPoint(point:) 方法,即我不想编写手动检查,例如 for 循环运行 cell.frame.containsPoint(point:)

我试图更改单元格层的 borderRadius,但我认为用于检测点击的相关字段是 frame,它是一个 CGRect ...所以我什至可以实现我正在尝试做的事情,还是我必须自己编写细胞检测代码? (类似于,获取所有单元格并计算到中心的距离,然后查看距离是否在半径内)

主要问题是我的布局导致单元格框架重叠,因此 indexPathForItemAtPoint(point:) 目前导致某些单元格在框架重叠时比其他单元格更受青睐(很可能基于迭代顺序visibleCells).

最佳答案

您可以创建一个 UIBezierPath 并检查点击是否在其中。例如,在您对 UITapGestureRecognizer 的操作中,您可以这样说

let location = sender.location
let indexPath = collectionView.indexPathForItemAtPoint(location)
let cell = collectionView.cellForItemAtIndexPath(indexPath!)
let newLocation = cell?.convertPoint(location, fromView: collectionView)
let circlePath = UIBezierPath(ovalInRect: (cell?.bounds)!)
if circlePath.containsPoint(newLocation!)
{
    //handle cell tap
}

或者在您的 UICollectionViewCell 子类中,您可以添加如下内容:

override func hitTest(point: CGPoint, withEvent e: UIEvent?) -> UIView? {
        let circlePath = UIBezierPath(ovalInRect: (self.bounds))
        if circlePath.containsPoint(point)
        {
            return self
        }
        return nil
    }

这将检查点击是否在 View 的可见部分或将事件传递给较低的 View 。然后实现 didSelectItemAtIndexPath 并在那里处理点击事件。

关于ios - 改变 UICollectionViewCell 手势命中框的形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35091207/

相关文章:

带有服务器的 ios 快速图像缓存

ios - 更改图像色调颜色内存泄漏

ios - 添加了 UITableViewCell GestureRecognizer 委托(delegate)不工作

iphone - UIView动画异常

ios - "Use of undeclared identifier ' Braintree '"在不使用 CocoaPods 的情况下手动集成 Braintree 后出现错误

iphone - 如何在没有已知框架的情况下初始化 View ?

ios - 如何在合并音频和视频时循环音频

ios - Swift 结果未通过 Storyboard 添加的 SearchBar 进行更新

ios - UISwipeGestureRecognizer 似乎不尊重 iPhone 3G 上当前的 UIDevice 方向

ios - 在 Unity iOS 上打开设置应用程序