<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      UICollectionView 04 - 仿UITableView 懸浮Header

      一,概述

        基于單section設計布局下實現的UICollectionView Header懸浮功能,多section的思路類似。

      二,思路

        在UITableView中,Header懸浮功能只需設置TableView的style即可實現,但在UICollectionView中由于布局分離出來了,需要在布局中自己計算實現。使用UICollectionView的supplementaryView來作為HeaderView,在方法

      //計算rect內的元素的UICollectionViewLayoutAttributes
      - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;

        中添加上計算SupplementaryView的UICollectionViewLayoutAttributes的邏輯,即可實現此功能。

      三,修改自定義的布局

          在自定義的布局類中需要處理的方法有3個:

      • 在上面的第一個方法中,除了計算item的UICollectionViewLayoutAttributes外,加上計算SupplementaryView的UICollectionViewLayoutAttributes的邏輯。
        /// 當CollectionView開始刷新后,會調用此方法并傳遞rect參數(即當前可視區域)
        /// @param rect 我們需要利用rect參數判斷出在當前可視區域中有哪幾個indexPath會被顯示(無視rect而全部計算將會帶來不好的性能)
        /// 最后計算相關indexPath的layoutAttributes,加入數組中并返回
        - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
            NSMutableArray *attributesArray = self.attributesArray;
            NSArray<NSIndexPath *> *indexPaths;
            //1、計算rect中出現的items
            indexPaths = [self p_indexPathForItemsInRect:rect];
            for(NSIndexPath *indexPath in indexPaths){
                //計算對應的LayoutAttributes
                UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
                [attributesArray addObject:attributes];
            }
            
            //2、計算rect中出現的SupplementaryViews
            //這里只計算了kSupplementaryViewKindHeader
            indexPaths = [self p_indexPathForSupplementaryViewsOfKind:kSupplementaryViewKindHeader InRect:rect];
            for(NSIndexPath *indexPath in indexPaths){
                //計算對應的LayoutAttributes
                UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:kSupplementaryViewKindHeader atIndexPath:indexPath];
                [attributesArray addObject:attributes];
            }
            return attributesArray;
        }
        
        ///計算目標rect中含有的某類SupplementaryView
        - (NSMutableArray<NSIndexPath *> *)p_indexPathForSupplementaryViewsOfKind:(NSString *)kind InRect:(CGRect)rect {
            NSMutableArray<NSIndexPath *> *indexPaths = [NSMutableArray array];
            if([kind isEqualToString:kSupplementaryViewKindHeader]){
                //在這個瀑布流自定義布局中,只有一個位于列表頂部的SupplementaryView
                NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
                
                //如果當前區域可以看到SupplementaryView,則返回
                //CGFloat height = [self.delegate collectionViewLayout:self heightForSupplementaryViewAtIndexPath:indexPath];
                //if(CGRectGetMinY(rect) <= height + _insets.top){
                //Header默認總是需要顯示
                [indexPaths addObject:indexPath];
                //}
            }
            return indexPaths;
        }

        用kSupplementaryViewKindHeader來分辨不同的SupplementaryView。indexPathForSupplementaryViewsOfKind: InRect:方法用于計算在rect內需要展示那些指定kind的SupplementaryView

      • 重寫父類的 -layoutAttributesForSupplementaryViewOfKind:atIndexPath:方法,計算指定kind和indexPath上的SupplementaryView的LayoutAttributes

        ///MARK:根據kind、indexPath,計算對應的LayoutAttributes
        - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];
            
            //計算LayoutAttributes
            if([elementKind isEqualToString:kSupplementaryViewKindHeader]){
                CGFloat w = self.collectionView.bounds.size.width;
                CGFloat h = [self.delegate lx_collectionViewLayout:self heightForSupplementaryViewAtIndexPath:indexPath];
                CGFloat x = 0;
                //根據offset計算kSupplementaryViewKindHeader的y
                //y = offset.y-(header高度-固定高度)
                CGFloat offsetY = self.collectionView.contentOffset.y;
                CGFloat y = MAX(0,offsetY-(h-kSupplementaryViewKindHeaderPinnedHeight));
                attributes.frame = CGRectMake(x, y, w, h);
                attributes.zIndex = 1024;
            }
            return attributes;
        }

        為了顯示HeaderView并讓其懸浮在列表頂部,需要知道它的高度,所以添加代理方法collectionViewLayout:heightForSupplementaryViewAtIndexPath:來獲取高度,同時設置zIndex讓其保持在所有視圖的最前方。在這個方法中,主要計算HeaderView在CollectionView中的y坐標,保證在CollectionView的滾動過程中,HeaderView始終在CollectionView的頂部露出固定高度。


      • InvalidateLayout 最后需要覆蓋父類的shouldInvalidateLayoutForBoundsChange方法,讓其返回YES,使UICollectionView在滑動時不斷刷新Layout

         ///每當offset改變時,是否需要重新布局,newBounds為offset改變后的rect
         ///瀑布流中不需要,因為滑動時,cell的布局不會隨offset而改變
         ///如果需要實現懸浮Header,需要改為YES
        - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
            //return [super shouldInvalidateLayoutForBoundsChange:newBounds];
            return YES;
        }

      四,最后

        最后創建我們的自定義headerView,在collectionView初始化的時候注冊,并在UICollectionViewDataSource的代理方法中創建相應的HeaderView就大功告成啦。




      posted on 2020-07-30 14:21  梁飛宇  閱讀(1290)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国产精品成人国产乱| 男人又大又硬又粗视频| 国产精品99一区二区三区| 美女18禁一区二区三区视频| 少妇被日自拍黄色三级网络| 国产精品入口中文字幕| 在线a亚洲老鸭窝天堂| 亚洲综合一区二区三区| 国产精品先锋资源站先锋影院| 国精品人妻无码一区免费视频电影 | 福利一区二区在线视频| 欧美成人h精品网站| 亚洲欧美日韩第一页| 国产午夜精品理论片久久影院| 东京热无码av男人的天堂| 在线精品国精品国产不卡| 熟女系列丰满熟妇AV| 最新国产精品亚洲| 狠狠躁天天躁中文字幕无码| 国产成AV人片久青草影院| 国产99视频精品免费视频76| 337p粉嫩大胆噜噜噜| 日本久久一区二区三区高清| 亚洲日本欧美日韩中文字幕| 亚洲欧洲日产国无高清码图片| 国产色无码专区在线观看| 国产精品自在线拍国产手机版| 亚洲国产日韩一区三区| 999国产精品999久久久久久| 人妻中文字幕在线视频无码| AV无码免费不卡在线观看| 亚洲高清av一区二区| 性欧美大战久久久久久久 | 中文字幕自拍偷拍福利视频| 最新永久免费AV无码网站| 亚洲婷婷综合色高清在线 | 精品人妻少妇一区二区三区在线| 久久人人97超碰人人澡爱香蕉| 人妻中文字幕一区二区三| b站永久免费看片大全| 国模雨珍浓密毛大尺度150p|