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

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

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

      UICollectionView 02 - 自定義局篇

      一,UICollectionViewLayout布局的具體思路:

      • 設置itemSzie屬性,它定義了每一個item的大小。在一個示例中通過設置layout的itemSize屬性全局的設置了cell的尺寸。

        - (CGSize)collectionView:(UICollectionView *)collectionView
                         layout:(UICollectionViewLayout*)collectionViewLayout
          sizeForItemAtIndexPath:(NSIndexPath *)indexPath
      • 設置間隔

        間隔可以指定item之間的間隔和每一行之間的間隔。間隔和itemSzie一樣,既有全局屬性,也可以對每一個item設定:
        @property (nonatomic) CGFloat minimumLineSpacing;
        @property (nonatomic) CGFloat minimumInteritemSpacing;
        - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
        - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
      • 設定滾動方向

        typedef NS_ENUM(NSInteger, UICollectionViewScrollDirection) { 
           UICollectionViewScrollDirectionVertical, 
           UICollectionViewScrollDirectionHorizontal 
        };
      • 設置Header和Footer的尺寸

        設置Header和Footer的尺寸也分為全局和局部。在這里需要注意滾動的方向,滾動方向不同,header和footer的寬度和高度只有一個會起作用。垂直滾動時section間寬度為尺寸的高。
        @property (nonatomic) CGSize headerReferenceSize;
        @property (nonatomic) CGSize footerReferenceSize;
        - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
        - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
      • 設置內邊距

        @property (nonatomic) UIEdgeInsets sectionInset;
        - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section

      二,用UICollectionView實現瀑布流

        實現瀑布流的方式有幾種,但是比較簡單的是通過UICollectionView,因為collectionView自己會實現cell的循環利用,所以自己不用實現循環利用的機制。瀑布就最重要的就是布局,要選取最短的那一列來排布,保證每一列之間的間距不會太大。

      實現步驟

      • 自定義繼承自UICollectionViewLayout的子類來進行實現布局

        • 調用- (void)prepareLayout進行初始化
        • 重載- (CGSize)collectionViewContentSize返回內容的大小
        • 重載- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect方法返回rect中所有元素的布局屬性,返回的是一個數組
        • 重載- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath方法返回對應的indexPath的位置的cell的布局屬性。
        • 重載- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;方法返回對應indexPath的位置的追加視圖的布局屬性,如果沒有就不用重載
        • 重載- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;方法返回對應indexPath的位置的裝飾視圖的布局屬性,如果沒有也不需要重載
        • 重載- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;當邊界發生改變時,是否應該刷新。

      三,自定義UICollectionViewLayout布局的示例代碼

        用代理來實現對item的布局屬性的控制

      • .h文件

        #import <UIKit/UIKit.h>
        @class LMHWaterFallLayout;
        
        @protocol  LMHWaterFallLayoutDeleaget<NSObject>
        @required
        /**
         * 每個item的高度
         */
        - (CGFloat)waterFallLayout:(LMHWaterFallLayout *)waterFallLayout heightForItemAtIndexPath:(NSUInteger)indexPath itemWidth:(CGFloat)itemWidth;
        
        @optional
        /**
         * 有多少列
         */
        - (NSUInteger)columnCountInWaterFallLayout:(LMHWaterFallLayout *)waterFallLayout;
        
        /**
         * 每列之間的間距
         */
        - (CGFloat)columnMarginInWaterFallLayout:(LMHWaterFallLayout *)waterFallLayout;
        
        /**
         * 每行之間的間距
         */
        - (CGFloat)rowMarginInWaterFallLayout:(LMHWaterFallLayout *)waterFallLayout;
        
        /**
         * 每個item的內邊距
         */
        - (UIEdgeInsets)edgeInsetdInWaterFallLayout:(LMHWaterFallLayout *)waterFallLayout;
        
        @end
        
        @interface LMHWaterFallLayout : UICollectionViewLayout
        /** 代理 */
        @property (nonatomic, weak) id<LMHWaterFallLayoutDeleaget> delegate;
        
        @end
      • .m文件

        #import "LMHWaterFallLayout.h"
        
        /** 默認的列數    */
        static const CGFloat LMHDefaultColunmCount = 3;
        /** 每一列之間的間距    */
        static const CGFloat LMHDefaultColunmMargin = 10;
        /** 每一行之間的間距    */
        static const CGFloat LMHDefaultRowMargin = 10;
        
        /** 內邊距    */
        static const UIEdgeInsets LMHDefaultEdgeInsets = {10,10,10,10};
        @interface LMHWaterFallLayout()
        /** 存放所有的布局屬性 */
        @property (nonatomic, strong) NSMutableArray * attrsArr;
        /** 存放所有列的當前高度 */
        @property (nonatomic, strong) NSMutableArray *columnHeights;
        /** 內容的高度 */
        @property (nonatomic, assign) CGFloat contentHeight;
        
        - (NSUInteger)colunmCount;
        - (CGFloat)columnMargin;
        - (CGFloat)rowMargin;
        - (UIEdgeInsets)edgeInsets;
        
        @end
        
        @implementation LMHWaterFallLayout
        
        #pragma mark 懶加載
        - (NSMutableArray *)attrsArr{
            if (!_attrsArr) {
                _attrsArr = [NSMutableArray array];
            }
            return _attrsArr;
        }
        
        - (NSMutableArray *)columnHeights{
            if (!_columnHeights) {
                _columnHeights = [NSMutableArray array];
            }
            return _columnHeights;
        }
        
        #pragma mark - 數據處理
        /**
         * 列數
         */
        - (NSUInteger)colunmCount{
            
            if ([self.delegate respondsToSelector:@selector(columnCountInWaterFallLayout:)]) {
                return [self.delegate columnCountInWaterFallLayout:self];
            }else{
                return LMHDefaultColunmCount;
            }
        }
        
        /**
         * 列間距
         */
        - (CGFloat)columnMargin{
            if ([self.delegate respondsToSelector:@selector(columnMarginInWaterFallLayout:)]) {
                return [self.delegate columnMarginInWaterFallLayout:self];
            }else{
                return LMHDefaultColunmMargin;
            }
        }
        
        /**
         * 行間距
         */
        - (CGFloat)rowMargin{
            if ([self.delegate respondsToSelector:@selector(rowMarginInWaterFallLayout:)]) {
                return [self.delegate rowMarginInWaterFallLayout:self];
            }else{
                return LMHDefaultRowMargin;
            }
        }
        
        /**
         * item的內邊距
         */
        - (UIEdgeInsets)edgeInsets{
            if ([self.delegate respondsToSelector:@selector(edgeInsetdInWaterFallLayout:)]) {
                return [self.delegate edgeInsetdInWaterFallLayout:self];
            }else{
                return LMHDefaultEdgeInsets;
            }
        }
        
        /**
         * 初始化
         */
        - (void)prepareLayout{
            [super prepareLayout];
            self.contentHeight = 0;
            // 清除之前計算的所有高度
            [self.columnHeights removeAllObjects];
            // 設置每一列默認的高度
            for (NSInteger i = 0; i < LMHDefaultColunmCount ; i ++) {
                [self.columnHeights addObject:@(LMHDefaultEdgeInsets.top)];
            }
            // 清楚之前所有的布局屬性
            [self.attrsArr removeAllObjects];
            // 開始創建每一個cell對應的布局屬性
            NSInteger count = [self.collectionView numberOfItemsInSection:0];
            for (int i = 0; i < count; i++) {
                // 創建位置
                NSIndexPath * indexPath = [NSIndexPath indexPathForItem:i inSection:0];
                // 獲取indexPath位置上cell對應的布局屬性
                UICollectionViewLayoutAttributes * attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
                [self.attrsArr addObject:attrs];
            }    
        }
        
        /**
         * 返回indexPath位置cell對應的布局屬性
         */
        - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
            // 創建布局屬性
            UICollectionViewLayoutAttributes * attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            //collectionView的寬度
            CGFloat collectionViewW = self.collectionView.frame.size.width;
            // 設置布局屬性的frame
            CGFloat cellW = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.colunmCount - 1) * self.columnMargin) / self.colunmCount;
            CGFloat cellH = [self.delegate waterFallLayout:self heightForItemAtIndexPath:indexPath.item itemWidth:cellW];
            // 找出最短的那一列
            NSInteger destColumn = 0;
            CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
            
            for (int i = 1; i < LMHDefaultColunmCount; i++) {
                // 取得第i列的高度
                CGFloat columnHeight = [self.columnHeights[i] doubleValue];
                
                if (minColumnHeight > columnHeight) {
                    minColumnHeight = columnHeight;
                    destColumn = i;
                }
            }
            
            CGFloat cellX = self.edgeInsets.left + destColumn * (cellW + self.columnMargin);
            CGFloat cellY = minColumnHeight;
            if (cellY != self.edgeInsets.top) {
                
                cellY += self.rowMargin;
            }
        
            attrs.frame = CGRectMake(cellX, cellY, cellW, cellH);
            
            // 更新最短那一列的高度
            self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
            
            // 記錄內容的高度 - 即最長那一列的高度
            CGFloat maxColumnHeight = [self.columnHeights[destColumn] doubleValue];
            if (self.contentHeight < maxColumnHeight) {
                self.contentHeight = maxColumnHeight;
            }
            return attrs;
        }
        
        /**
         * 決定cell的布局屬性
         */
        - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
            return self.attrsArr;
        }
        
        /**
         * 內容的高度
         */
        - (CGSize)collectionViewContentSize{
            return CGSizeMake(0, self.contentHeight + self.edgeInsets.bottom);
        }
      • 結果

      四,demo及注意  

        1.瀑布流中自定的cell時,不能使用純frame布局,這是因為cell存在復用的問題。如果在初始化方法中直接使用frame布局,就會在復用cell時,造成cell內容與cell的控件存在混亂。
        2.demo

       

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

      主站蜘蛛池模板: 高清偷拍一区二区三区| 亚洲精品视频免费| 少妇被躁爽到高潮| 蜜臀久久精品亚洲一区| 国产91精品调教在线播放 | 日韩av在线不卡一区二区| 亚洲av熟女国产一二三| 又大又长粗又爽又黄少妇毛片| 国内精品久久久久影院日本| 滁州市| 欧美亚洲人成网站在线观看| 欧美不卡无线在线一二三区观| 久久精品亚洲精品国产区| 婷婷五月综合激情| 国产成人亚洲精品在线看| 国产成人综合久久精品下载| 日本免费视频| 2020国产成人精品视频| 国产熟女一区二区三区四区| 欧美日本中文| 国产精品高清中文字幕| 一面膜上边一面膜下边视频| 精品国产av一区二区果冻传媒| 亚洲av成人精品免费看| 无码国产69精品久久久久网站| 巩义市| 久久亚洲av成人一二三区| 美女禁区a级全片免费观看| 精品无码一区二区三区爱欲| 中文字幕国产精品av| 国产亚洲真人做受在线观看| 另类 专区 欧美 制服| 四虎在线成人免费观看| 日夜啪啪一区二区三区| 人妻无码∧V一区二区| 97欧美精品系列一区二区| 中文字幕有码无码AV| 熟女人妻视频| 国产成人久久综合第一区| 国产欧美丝袜在线二区| 国产精品人妻系列21p|