我正在使用带有Flow Layout的UICollectionView。我设置了标头,这是一个UICollectionReusableView,表现得像这样;
layout?.sectionHeadersPinToVisibleBounds = true
...
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header", for: indexPath as IndexPath)
header.layer.zPosition = -1
return header
}
这样可以获得所需的效果,当向上滚动单元格时,标题会保持固定但会落在常规单元格后面。
但是,如果我尝试单击向上滚动的UICollectionViewCell,即技术上覆盖UICollectionReusableView,则UICollectionViewCell的didSelectItemAt tap事件不再触发,直到我将其向下滚动远离标题所在的位置。换句话说,UICollectionReusableView阻止了点击手势,即使它的zPosition设置为-1并且不可见。
有没有人遇到过这个问题,你是如何解决这个问题的?
答案 0 :(得分:1)
将其添加到Section Header视图类:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
会将所有触摸传递到下面的下一个接收器 - 在这种情况下,是您的集合视图单元格。如果在Section Header中需要交互式元素(例如按钮),则可以执行以下操作:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let ptInSub = theButton.convert(point, from: theButton.superview)
if theButton.bounds.contains(ptInSub) {
return true
}
return false
}
这个可以给你你想要的东西,虽然......如果Cell View覆盖了Section Header上的Button,你点击按钮所在的单元格,按钮将会挖掘。应该能够用另一个contains(point)
或两个......来解决这个问题。
答案 1 :(得分:0)
我最终在我的UICollectionReusableView标题中添加了Parallax效果。有一些Parallax库,但它实际上非常简单 - 我使用以下代码实现了它;
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if header != nil {
let scrollDiff = scrollView.contentOffset.y - self.previousScrollOffset
let absoluteTop: CGFloat = 0;
let absoluteBottom: CGFloat = scrollView.contentSize.height - scrollView.frame.size.height;
let isScrollingDown = scrollDiff > 0 && scrollView.contentOffset.y > absoluteTop
let isScrollingUp = scrollDiff < 0 && scrollView.contentOffset.y < absoluteBottom
var newHeight = self.headerHeight
if isScrollingDown {
newHeight = max(self.minHeaderHeight, self.headerHeight - abs(scrollDiff))
} else if isScrollingUp {
newHeight = min(self.maxHeaderHeight, self.headerHeight + abs(scrollDiff))
}
if newHeight != self.headerHeight {
self.headerHeight = newHeight
self.collectionView?.contentOffset = CGPoint(x: (self.collectionView?.contentOffset.x)!, y: self.previousScrollOffset)
self.collectionView?.collectionViewLayout.invalidateLayout()
}
self.previousScrollOffset = scrollView.contentOffset.y
}
}
然后改变标题的高度(在invalidateLayout()时调用);
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.bounds.width, height:self.headerHeight)
}
结果是不会发生任何重叠,但它仍然会产生我想要首先实现的预期效果。