国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

IOS中封裝自定義布局的步驟

2020-02-19 15:53:38
字體:
供稿:網(wǎng)友

不管做什么項(xiàng)目,有很多地方都是需要用到自己自定義的,那么IOS中簡(jiǎn)單的封裝要怎么布局呢?IOS中封裝自定義布局的步驟大家了解嗎?一起跟著武林技術(shù)頻道小編的步伐來了解一下吧!

一、概述
1、對(duì)于經(jīng)常使用的控件或類,通常將其分裝為一個(gè)單獨(dú)的類來供外界使用,以此達(dá)到事半功倍的效果
2、由于分裝的類不依賴于其他的類,所以若要使用該類,可直接將該類拖進(jìn)項(xiàng)目文件即可
3、在進(jìn)行分裝的時(shí)候,通常需要用到代理設(shè)計(jì)模式
二、代理設(shè)計(jì)模式
1、代理設(shè)計(jì)模式的組成
客戶類(通常作為代理):通常委托這是角色來完成業(yè)務(wù)邏輯
真實(shí)角色:將客戶類的業(yè)務(wù)邏輯轉(zhuǎn)化為方法列表,即代理協(xié)議
代理協(xié)議:

  • 定義了需要實(shí)現(xiàn)的業(yè)務(wù)邏輯
  • 定義了一組方法列表,包括必須實(shí)現(xiàn)的方法或選擇實(shí)現(xiàn)的方法
  • 代理協(xié)議是代理對(duì)象所要遵循一組規(guī)則

代理角色

  • 若要作為代理,需要遵守代理協(xié)議,并且實(shí)現(xiàn)必須實(shí)現(xiàn)的代理方法
  • 代理角色可以通過調(diào)用代理協(xié)議中的方法完成業(yè)務(wù)邏輯,也可以附加自己的操作

文字描述通常是抽象的,一下通過圖示來闡述代理設(shè)計(jì)模式

三、自定義布局類的封裝
1、業(yè)務(wù)邏輯
如圖

2、布局每個(gè)cell的業(yè)務(wù)邏輯
由于設(shè)置每個(gè)cell的布局屬性的業(yè)務(wù)邏輯較復(fù)雜,特附上如下思維導(dǎo)圖

3、封裝思路封裝需要根據(jù)客戶類業(yè)務(wù)邏輯需求來提供接口
1)、通過代理協(xié)議的可選實(shí)現(xiàn)的方法獲取的屬性值的屬性,需要設(shè)置默認(rèn)值
2)、未提供默認(rèn)值的且必須使用的屬性,需要通過必須實(shí)現(xiàn)的方法來獲得
3)、自定義布局提供的接口可選

  • 列數(shù)
  • 列之間的間距
  • 行之間的間距
  • 內(nèi)邊距

4)、自定義布局提供的接口必選
每個(gè)元素的高度,寬度可以通過列數(shù)和列間距計(jì)算得到
四、封裝步驟
設(shè)置代理協(xié)議,提供接口

//聲明LYPWaterFlowLayout為一個(gè)類@class LYPWaterFlowLayout;@protocol LYPWaterFlowLayoutDelegate //必須實(shí)現(xiàn)的方法@required/**獲取瀑布流每個(gè)元素的高度*/- (CGFloat)waterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout heightForItemAtIndex:(NSInteger)index itemWith:(CGFloat)itemWith;//可選實(shí)現(xiàn)的方法@optional/**獲取瀑布流的列數(shù)*/- (NSInteger)columnCountInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流列間距*/- (CGFloat)columnMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流的行間距*/- (CGFloat)rowMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;/**獲取瀑布流的內(nèi)邊距*/- (UIEdgeInsets)edgeInsetsInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout;@end

設(shè)置代理屬性

@interface LYPWaterFlowLayout : UICollectionViewLayout/**代理*/@property (nonatomic, weak) id delegate;@end

設(shè)置通過可選代理方法獲取屬性值的屬性的默認(rèn)值

/**默認(rèn)的列數(shù)*/static const NSInteger LYPDefaultColumnCount = 3;/**默認(rèn)每一列之間的間距*/static const CGFloat LYPDefaultColumMargin = 10;/**默認(rèn)每一行之間的間距*/static const CGFloat LYPDefaultRowMargin = 10;/**默認(rèn)邊緣間距*/static const UIEdgeInsets LYPDefaultEdgeInsets = {10, 10, 10, 10};

設(shè)置通過可選代理方法獲取屬性值的屬性的訪問方式若代理提供屬性值,則忽略默認(rèn)值

- (NSInteger)columnCount{  //判斷代理是否實(shí)現(xiàn)了獲取列數(shù)的可選方法  if ([self.delegate respondsToSelector:@selector(columnCountInWaterFlowLayout:)])  {    //實(shí)現(xiàn),返回通過代理設(shè)置的列數(shù)    return [self.delegate columnCountInWaterFlowLayout:self];  }  else  {    //為實(shí)現(xiàn),返回默認(rèn)的列數(shù)    return LYPDefaultColumnCount;  }}

注:其他屬性值的獲取與上述方法幾乎完全相同,不再贅述
設(shè)置布局
1)、設(shè)置需要的成員屬性

/**所有cell的布局屬性*/@property (nonatomic, strong) NSMutableArray *attrsArray;/**所有列的當(dāng)前高度*/@property (nonatomic, strong) NSMutableArray *columnHeights;

2)、通過懶加載的方式初始化成員屬性

/**--attrsArray--懶加載*/- (NSMutableArray *)attrsArray{  if (_attrsArray == nil)  {    _attrsArray = [NSMutableArray array];  }  return _attrsArray;}/**--columnHeights--懶加載*/- (NSMutableArray *)columnHeights{  if (_columnHeights == nil)  {    _columnHeights = [NSMutableArray array];  }  return _columnHeights;}

3)、初始化布局

- (void)prepareLayout{  [super prepareLayout];  /**清除之前跟布局相關(guān)的所有屬性,重新設(shè)置新的布局*/  //清除之前計(jì)算的所有列的高度  [self.columnHeights removeAllObjects];  //設(shè)置所有列的初始高度  for (NSInteger i = 0; i

4)、返回包含所有cell的布局屬性的數(shù)組

?

- (nullable NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{  return self.attrsArray;}設(shè)置每一個(gè)cell的布局屬性- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(nonnull NSIndexPath *)indexPath{  //獲取indexPath位置的布局屬性  UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];  /**設(shè)置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];  /***設(shè)置cell的位置***/  NSInteger destColumn = 0;  CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];  for (NSInteger i = 1; i columnHeight)    {      minColumnHeight = columnHeight;      destColumn = i;    }  }  //計(jì)算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;}

5)、設(shè)置collectionView內(nèi)容的尺寸

- (CGSize)collectionViewContentSize{  //獲取最高的那一列的高度  CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];  for (NSInteger i = 1; i

以上就是IOS中封裝自定義布局的步驟,相信大家都有了一定的了解,想要了解更多的技術(shù)信息,請(qǐng)繼續(xù)關(guān)注武林技術(shù)頻道吧!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 长治县| 林西县| 家居| 沧源| 二手房| 马鞍山市| 仙游县| 道孚县| 邛崃市| 全椒县| 滨州市| 南皮县| 黎川县| 赤壁市| 威远县| 钦州市| 乌拉特中旗| 塔河县| 黔南| 霍城县| 五指山市| 若尔盖县| 金山区| 鱼台县| 宁晋县| 铜梁县| 美姑县| 云南省| 柳江县| 黔江区| 凤凰县| 南阳市| 南靖县| 磐安县| 安国市| 绩溪县| 米易县| 当雄县| 丰县| 电白县| 宽甸|