在使用 UICollectionViewFlowLayout 并且开启 header 吸附时,如果 header 的背景是透明的,会出现 header 跟 cell 重叠的现象,同样 UITableView 可能也会有这种使用场景
解决方法就是修改 cell.layer.mask,以 UICollectionView 为例:
+ (void)_adjustCellMaskForHeaderOverlapWithCollectionView:(UICollectionView *)collectionView willDisplayCell:(UIView *)willDisplayCell {
UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout;
CGPoint contentOffset = collectionView.contentOffset;
NSMutableArray *visibleCells = [NSMutableArray arrayWithArray:[collectionView visibleCells]];
// 将要显示的 cell 也参与检测,修复下拉时顶部 cell 一闪一闪的问题
if (willDisplayCell) {
[visibleCells addObject:willDisplayCell];
}
for (UIView *cell in visibleCells) {
NSIndexPath *indexPath = [collectionView indexPathForCell:(UICollectionViewCell *)cell];
double headerHeight = 0;
if ([layout respondsToSelector:@selector(headerReferenceSize)]) {
headerHeight = [layout headerReferenceSize].height;
}
id<UICollectionViewDelegateFlowLayout> layoutDelegate = (id<UICollectionViewDelegateFlowLayout>)collectionView.delegate;
if ([layoutDelegate respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)]) {
headerHeight = [layoutDelegate collectionView:collectionView layout:collectionView.collectionViewLayout referenceSizeForHeaderInSection:indexPath.section].height;
}
double threshold = contentOffset.y + headerHeight;
CALayer *maskLayer = cell.layer.mask;
if (maskLayer == nil) {
maskLayer = [CALayer layer];
maskLayer.backgroundColor = [UIColor whiteColor].CGColor;
cell.layer.mask = maskLayer;
}
CGRect maskFrame = cell.bounds;
if (cell.frame.origin.y < threshold) {
double diff = threshold - cell.frame.origin.y;
maskFrame.origin.y = diff;
}
if (cell == willDisplayCell) {
maskFrame.size.height = 0;
}
[CATransaction begin];
[CATransaction setDisableActions:YES];
maskLayer.frame = maskFrame;
[CATransaction commit];
}
}
修复后
UITableView 的处理方案同理,具体可查看完整代码