如何将UICollectionViewCell的可触摸区域扩展到其范围之外?

时间:2015-04-04 21:27:20

标签: cocoa-touch swift uicollectionview uicollectionviewcell multi-touch

我有一个集合视图单元格,其标签延伸到单元格的边界之外。单元格不会剪切标签。我希望didSelectItemAtIndexPath检测选择,如果用户点击超出单元格边界的标签部分。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

子视图的可触摸性通常不会超出超视图的范围。因此,您需要对集合视图单元类进行命中测试,以便即使触摸超出单元格范围,其子视图也可以触摸。

在我的书中,我提供example(您可以在机器上下载并试用),其工作原理如下:

override func hitTest(_ point: CGPoint, with e: UIEvent?) -> UIView? {
    if let result = super.hitTest(point, with:e) {
        return result
    }
    for sub in self.subviews.reversed() {
        let pt = self.convert(point, to:sub)
        if let result = sub.hitTest(pt, with:e) {
            return result
        }
    }
    return nil
}

但是,您可能需要稍微调整一下,因为标签可能不是单元格的直接子视图(如示例代码中所假设的)。但是,它确实显示了这个想法。

答案 1 :(得分:0)

实现此目的的一种方法是继承UICollectionViewCell并覆盖pointInside(_:withEvent:),如果该点位于单元格标签内,则返回true

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    let pointInLabelCoords = convertPoint(point, toView: label)
    if label.pointInside(pointInLabelCoords, withEvent: event) {
        return true
    }
    return super.pointInside(point, withEvent: event)
}

或者,如果您需要一个更强大的解决方案,允许触摸任何越界子视图,只需枚举contentView.subviews并询问每个视图该点是否在内部。

请记住,只有当单元格(包括其可触摸的越界子视图)完全包含在单元格的超级视图中时,此方法才有效。这是因为当系统查找视图以响应触摸时遍历视图层次结构的方式(请参阅hitTest(_:withEvent:))。如果可触摸区域位于单元格的超视图边界之外,您还需要在 视图(集合视图)上覆盖pointInside(_:withEvent:)