美文网首页
UICollectionViewLayoutInvalidati

UICollectionViewLayoutInvalidati

作者: irisg80236 | 来源:发表于2020-04-21 11:51 被阅读0次

    UICollectionView 关于自定义layout的一点见解

    @interface CollectionWaterfallLayout : UICollectionViewLayout
    
    /**
     *  1、
     *  collectionView reload、invalidateLayout方法后会调用此方法
     *  此方法中可能涉及大量布局运算
    */
    - (void)prepareLayout
    {
        [super prepareLayout];
        // code...
    }
    
    // newBounds 改变时给出条件是否需要将layout失效
    // return YES to cause the collection view to requery the layout for geometry 
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds; information
    
    // shouldInvalidateLayoutForBoundsChange 返回YES时调用,否则不调用
    - (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds
    

    可以在这里获取到UICollectionViewLayoutInvalidationContext,并主动调用以下方法完成具体的indexPath布局失效。

    - (void)invalidateItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths API_AVAILABLE(ios(8.0));
    - (void)invalidateSupplementaryElementsOfKind:(NSString *)elementKind atIndexPaths:(NSArray<NSIndexPath *> *)indexPaths API_AVAILABLE(ios(8.0));
    - (void)invalidateDecorationElementsOfKind:(NSString *)elementKind atIndexPaths:(NSArray<NSIndexPath *> *)indexPaths API_AVAILABLE(ios(8.0));
    

    同时,collectionView会主动询问以下方法得到新的布局信息

    - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
    - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
    - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;
    

    多次实验后得到的现象如下:
    1.shouldInvalidateLayoutForBoundsChange->YES
    2.invalidationContextForBoundsChange 不实现
    3.prepareLayout 在每次滑动都会调用

    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
        return YES;
    }
    /*
    - (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds {
        UICollectionViewLayoutInvalidationContext*context = [super invalidationContextForBoundsChange:newBounds];
        return context;
    }
     */
    - (void)prepareLayout
    {
        [super prepareLayout];
        // code...
    }
    

    实现了invalidationContextForBoundsChange,并在内部具体失效某个indexPath布局,那么prepareLayout并不会触发调用,会触发layoutAttributesForSupplementaryViewOfKind

    - (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds {
        UICollectionViewLayoutInvalidationContext*context = [super invalidationContextForBoundsChange:newBounds];
        [context invalidateSupplementaryElementsOfKind:kSupplementaryViewKindHeader atIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]]];
        return context;
    }
    - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
    {
       // 返回新的布局
    }
    

    通过此方法避免prepareLayout的频繁调用也是一种性能优化

    相关文章

      网友评论

          本文标题:UICollectionViewLayoutInvalidati

          本文链接:https://www.haomeiwen.com/subject/boayihtx.html