iOS 透明 header 跟 cell 重叠

2024-12-14  本文已影响0人  nzkaw

在使用 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 的处理方案同理,具体可查看完整代码


完整代码

上一篇 下一篇

猜你喜欢

热点阅读