Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa touch 如何将UICollectionViewCell的可触摸区域扩展到其边界之外?_Cocoa Touch_Swift_Uicollectionview_Uicollectionviewcell_Multi Touch - Fatal编程技术网

Cocoa touch 如何将UICollectionViewCell的可触摸区域扩展到其边界之外?

Cocoa touch 如何将UICollectionViewCell的可触摸区域扩展到其边界之外?,cocoa-touch,swift,uicollectionview,uicollectionviewcell,multi-touch,Cocoa Touch,Swift,Uicollectionview,Uicollectionviewcell,Multi Touch,我有一个集合视图单元格,其标签延伸到单元格边界之外。单元格不会剪裁标签。如果用户点击标签超出单元格边界的部分,我希望didSelectItemAtIndexPath检测选择。如何做到这一点?实现这一点的一种方法是将UICollectionViewCell子类化,并覆盖pointInside(:withEvent:)以返回true,如果该点位于单元格标签内: override func pointInside(point: CGPoint, withEvent event: UIEvent?) -

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

实现这一点的一种方法是将
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.subview
,并询问每个视图该点是否在内部


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

子视图的可触摸性通常不会延伸到superview的边界之外。因此,您需要对集合视图单元格类进行命中测试,以便即使触摸超出单元格的边界,其子视图也是可触摸的

在我的书中,我给出了一个(您可以下载并在您的机器上试用)如下工作方式:

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
}

不过,您可能需要对此进行一些调整,因为标签可能不是单元格的直接子视图(如该示例代码中所假设的)。但是,它确实表明了这一点。

有关这里涉及的理论和实践,请参阅我的早期版本: