亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

瀑布流-02-手把手教你封裝自定義布局

2019-11-14 18:22:58
字體:
來源:轉載
供稿:網友

概述


  • 對于經常使用的控件或類,通常將其分裝為一個單獨的類來供外界使用,以此達到事半功倍的效果
  • 由于分裝的類不依賴于其他的類,所以若要使用該類,可直接將該類拖進項目文件即可
  • 在進行分裝的時候,通常需要用到代理設計模式

代理設計模式


  • 代理設計模式的組成

    • 客戶類(通常作為代理)

      • 通常委托這是角色來完成業務邏輯
    • 真實角色

      • 將客戶類的業務邏輯轉化為方法列表,即代理協議
    • 代理協議

      • 定義了需要實現的業務邏輯
      • 定義了一組方法列表,包括必須實現的方法或選擇實現的方法
      • 代理協議是代理對象所要遵循一組規則
    • 代理角色

      • 若要作為代理,需要遵守代理協議,并且實現必須實現的代理方法
      • 代理角色可以通過調用代理協議中的方法完成業務邏輯,也可以附加自己的操作
  • 文字描述通常是抽象的,一下通過圖示來闡述代理設計模式

自定義布局類的封裝


  • 業務邏輯

    • 如圖

  • 布局每個cell的業務邏輯

    • 由于設置每個cell的布局屬性的業務邏輯較復雜,特附上如下思維導圖

  • 封裝思路封裝需要根據客戶類業務邏輯需求來提供接口

    • 通過代理協議的可選實現的方法獲取的屬性值的屬性,需要設置默認值
    • 未提供默認值的且必須使用的屬性,需要通過必須實現的方法來獲得
    • 自定義布局提供的接口可選

      • 列數
      • 列之間的間距
      • 行之間的間距
      • 內邊距
    • 自定義布局提供的接口必選

      • 每個元素的高度,寬度可以通過列數和列間距計算得到

封裝步驟


  • 設置代理協議,提供接口

    //聲明LYPWaterFlowLayout為一個類@class LYPWaterFlowLayout;@PRotocol LYPWaterFlowLayoutDelegate <NSObject>//必須實現的方法@required/**獲取瀑布流每個元素的高度*/- (CGFloat)waterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout heightForItemAtIndex:(NSInteger)index itemWith:(CGFloat)itemWith;//可選實現的方法@optional/**獲取瀑布流的列數*/- (NSInteger)columnCountInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流列間距*/- (CGFloat)columnMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流的行間距*/- (CGFloat)rowMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流的內邊距*/- (UIEdgeInsets)edgeInsetsInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;@end
  • 設置代理屬性

    @interface LYPWaterFlowLayout : UICollectionViewLayout/**代理*/@property (nonatomic, weak) id<LYPWaterFlowLayoutDelegate> delegate;@end
  • 設置通過可選代理方法獲取屬性值的屬性的默認值

    /**默認的列數*/static const NSInteger LYPDefaultColumnCount = 3;/**默認每一列之間的間距*/static const CGFloat LYPDefaultColumMargin = 10;/**默認每一行之間的間距*/static const CGFloat LYPDefaultRowMargin = 10;/**默認邊緣間距*/static const UIEdgeInsets LYPDefaultEdgeInsets = {10, 10, 10, 10};
  • 設置通過可選代理方法獲取屬性值的屬性的訪問方式若代理提供屬性值,則忽略默認值

    - (NSInteger)columnCount{    //判斷代理是否實現了獲取列數的可選方法    if ([self.delegate respondsToSelector:@selector(columnCountInWaterFlowLayout:)])    {        //實現,返回通過代理設置的列數        return [self.delegate columnCountInWaterFlowLayout:self];    }    else    {        //為實現,返回默認的列數        return LYPDefaultColumnCount;    }}
    • 注:其他屬性值的獲取與上述方法幾乎完全相同,不再贅述
  • 設置布局

    • 設置需要的成員屬性

      /**所有cell的布局屬性*/@property (nonatomic, strong) NSMutableArray *attrsArray;/**所有列的當前高度*/@property (nonatomic, strong) NSMutableArray *columnHeights;
    • 通過懶加載的方式初始化成員屬性

      /**--attrsArray--懶加載*/- (NSMutableArray *)attrsArray{    if (_attrsArray == nil)    {        _attrsArray = [NSMutableArray array];    }    return _attrsArray;}/**--columnHeights--懶加載*/- (NSMutableArray *)columnHeights{    if (_columnHeights == nil)    {        _columnHeights = [NSMutableArray array];    }    return _columnHeights;}
    • 初始化布局

      - (void)prepareLayout{    [super prepareLayout];    /**清除之前跟布局相關的所有屬性,重新設置新的布局*/    //清除之前計算的所有列的高度    [self.columnHeights removeAllObjects];    //設置所有列的初始高度    for (NSInteger i = 0; i<self.columnCount; i++)    {        self.columnHeights[i] = @(self.edgeInsets.top);    }    //清除之前所有的布局屬性    [self.attrsArray removeAllObjects];    /**開始創建每一個cell對應的布局屬性*/    NSInteger count = [self.collectionView numberOfItemsInSection:0];    for (NSInteger i = 0; i<count; i++)    {        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];        //獲取indexPath位置cell對應的布局屬性        UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];        //將indexPath位置的cell的布局屬性添加到所有cell的布局屬性數組中        [self.attrsArray addObject:attrs];    }}
    • 返回包含所有cell的布局屬性的數組

      - (nullable NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{    return self.attrsArray;}
    • 設置每一個cell的布局屬性

      - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(nonnull NSIndexPath *)indexPath{    //獲取indexPath位置的布局屬性    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];    /**設置cell布局屬性的frame*/    /***確定cell的尺寸***/    //獲取collectionView的寬度    CGFloat collectionViewWidth = self.collectionView.frame.size.width;    //cell寬度    CGFloat width = ((collectionViewWidth - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columMargin)) / self.columnCount;    //cell高度    CGFloat height = [self.delegate waterFlowLayout:self heightForItemAtIndex:indexPath.item itemWith:width];    /***設置cell的位置***/    NSInteger destColumn = 0;    CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];    for (NSInteger i = 1; i<self.columnCount; i++)    {        CGFloat columnHeight = [self.columnHeights[i] doubleValue];        if (minColumnHeight > columnHeight)        {            minColumnHeight = columnHeight;            destColumn = i;        }    }    //計算cell的位置    CGFloat x = self.edgeInsets.left + destColumn * (width + self.columMargin);    CGFloat y = minColumnHeight;    //判斷是不是第一行    if (y != self.edgeInsets.top)    {        //若不是第一行,需要加上行間距        y += self.rowMargin;    }    /**給cell的布局屬性的frame賦值*/    attrs.frame = CGRectMake(x, y, width, height);    //更新最短那列的高度    self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));    /**返回indexPath位置的cell的布局屬性*/    return attrs;}
    • 設置collectionView內容的尺寸

      - (CGSize)collectionViewContentSize{    //獲取最高的那一列的高度    CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];    for (NSInteger i = 1; i<self.columnCount; i++)    {        CGFloat columnHeight = [self.columnHeights[i] doubleValue];        if (maxColumnHeight < columnHeight)        {            maxColumnHeight = columnHeight;        }    }    //返回collectionView的contentSize,高度為最高的高度加上一個行間距    return CGSizeMake(0, maxColumnHeight + self.rowMargin);}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
538国产精品一区二区免费视频| 亚洲欧美日本精品| 77777亚洲午夜久久多人| 一区二区三区亚洲| 久久人人爽人人爽人人片亚洲| 亚洲视频在线免费观看| 欧美极品美女视频网站在线观看免费| 国产欧美va欧美va香蕉在| 高跟丝袜一区二区三区| 欧洲成人在线视频| 麻豆一区二区在线观看| 午夜精品福利在线观看| 国产精品免费久久久久久| 一区二区中文字幕| 日韩小视频网址| 久久久999精品免费| 精品精品国产国产自在线| 欧美激情欧美激情| 久久天天躁狠狠躁夜夜躁| 欧美极品美女视频网站在线观看免费| 91精品国产免费久久久久久| 成人夜晚看av| 成人av.网址在线网站| 国产精品日韩av| 国产成人精品在线| 久久久国产在线视频| 最近2019中文字幕mv免费看| 国产精品高潮呻吟久久av黑人| 国产99久久精品一区二区| 日韩中文字幕av| 欧美在线视频a| 日韩视频免费在线| 最近2019中文字幕第三页视频| 精品视频在线导航| 一区二区欧美日韩视频| 国产精品久久中文| 久国内精品在线| 欧美诱惑福利视频| 91手机视频在线观看| 亚洲国产天堂久久综合网| 国产不卡在线观看| 另类视频在线观看| 日韩av免费在线| 欧美福利视频网站| 日韩亚洲一区二区| 国产精品99导航| 亚洲最新av在线| 国产999精品久久久影片官网| 国产精品人成电影| 国a精品视频大全| 91亚洲精品在线观看| 国产精品h片在线播放| 国外成人在线直播| 国产精品女人网站| 亚洲一区国产精品| 欧美疯狂xxxx大交乱88av| 国产在线观看一区二区三区| 亚洲精品福利在线观看| 国产精品免费视频久久久| 97在线视频国产| 国产成人激情视频| 成人精品福利视频| 97精品在线视频| 国产精品久在线观看| 久久精品影视伊人网| 国内精品小视频| 亚洲欧洲一区二区三区久久| 欧美日韩一区二区三区在线免费观看| 亚洲一区二区在线| 日韩欧美福利视频| 亚洲视频在线观看网站| 成人www视频在线观看| 日本人成精品视频在线| 亚洲色图18p| 久久网福利资源网站| 国产成人午夜视频网址| 国语自产精品视频在免费| 一区二区三区美女xx视频| 国产精品一区二区久久久久| 91免费国产网站| 欧美大片免费观看在线观看网站推荐| 欧美中文字幕视频在线观看| 最新69国产成人精品视频免费| 国产精品中文字幕久久久| 日韩免费观看在线观看| 26uuu国产精品视频| 日韩在线欧美在线国产在线| 国产精品免费一区豆花| 精品高清一区二区三区| 少妇av一区二区三区| 亚洲欧美日韩在线一区| 亚洲精品大尺度| 亚洲第一天堂av| 欧美巨乳在线观看| 68精品国产免费久久久久久婷婷| 亚洲精品电影网站| 日韩精品极品在线观看播放免费视频| 欧美极品在线视频| 亚洲欧美国产日韩中文字幕| 91精品国产高清久久久久久91| 亚洲欧美激情四射在线日| 日韩高清电影好看的电视剧电影| 精品国产91久久久久久老师| 欧美午夜www高清视频| 欧美精品在线观看| 欧美一级大片视频| 国产精品大陆在线观看| 亚洲精品国精品久久99热一| 亚洲欧洲一区二区三区在线观看| 国产丝袜一区二区三区免费视频| 亚洲人成电影网站色www| 欧美性xxxxx极品| 亚洲网在线观看| 午夜精品一区二区三区视频免费看| 精品久久久999| 亚洲深夜福利网站| 精品中文字幕在线2019| 亚洲精品www久久久| 国产经典一区二区| 一本色道久久综合狠狠躁篇的优点| 久久久久久久久久久免费| 欧美性猛交xxxx富婆| 日韩欧美在线视频日韩欧美在线视频| 国产精品高潮呻吟久久av黑人| 在线色欧美三级视频| 亚洲美女精品成人在线视频| 岛国av在线不卡| 久久久久久久久爱| 情事1991在线| 国产精品自拍小视频| 欧美高清第一页| 97国产精品视频人人做人人爱| 亚洲欧洲在线播放| 久久99视频精品| 最近2019年好看中文字幕视频| 欧美日韩在线视频观看| 欧美日韩在线观看视频| 亚洲国产又黄又爽女人高潮的| 91国产在线精品| 国产在线日韩在线| 日韩av手机在线看| 欧美日韩在线观看视频小说| 亚洲欧美一区二区精品久久久| 1769国内精品视频在线播放| 欧美在线激情网| 国产久一一精品| 欧美精品免费播放| 亚洲成人精品久久久| 久久91亚洲精品中文字幕奶水| 日韩av影视综合网| 欧美亚洲国产精品| 欧美激情在线狂野欧美精品| 九九热精品在线| 久久人人爽人人| 日韩av免费一区| 日韩av在线免费播放| 国产91色在线播放| 国产综合福利在线| 欧美激情欧美激情在线五月| 欧美午夜激情视频| 久久中文精品视频| 欧美又大又硬又粗bbbbb| 亚洲aⅴ男人的天堂在线观看| 97久久精品视频|