1、概述
1、關於常常應用的控件或類,平日將其分裝為一個零丁的類來供外界應用,以此到達事半功倍的後果
2、因為分裝的類不依附於其他的類,所以若要應用該類,可直接將該類拖進項目文件便可
3、在停止分裝的時刻,平日須要用到署理設計形式
2、署理設計形式
1、署理設計形式的構成
客戶類(平日作為署理):平日拜托這是腳色來完成營業邏輯
真實腳色:將客戶類的營業邏輯轉化為辦法列表,即署理協定
署理協定:
署理腳色
文字描寫平日是籠統的,一下經由過程圖示來論述署理設計形式

3、自界說結構類的封裝
1、營業邏輯
如圖

2、結構每一個cell的營業邏輯
因為設置每一個cell的結構屬性的營業邏輯較龐雜,特附上以下思想導圖

3、封裝思緒封裝須要依據客戶類營業邏輯需求來供給接口
1)、經由過程署理協定的可選完成的辦法獲得的屬性值的屬性,須要設置默許值
2)、未供給默許值的且必需應用的屬性,須要經由過程必需完成的辦法來取得
3)、自界說結構供給的接口可選
4)、自界說結構供給的接口必選
每一個元素的高度,寬度可以經由過程列數和列間距盤算獲得
4、封裝步調
設置署理協定,供給接口
//聲明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;
}
}
注:其他屬性值的獲得與上述辦法簡直完整雷同,不再贅述
設置結構
1)、設置須要的成員屬性
/**一切cell的結構屬性*/ @property (nonatomic, strong) NSMutableArray *attrsArray; /**一切列確當前高度*/ @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];
/**消除之前跟結構相干的一切屬性,從新設置新的結構*/
//消除之前盤算的一切列的高度
[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];
}
}
4)、前往包括一切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;
}
5)、設置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);
}
以上就是本文的全體內容,願望對年夜家的進修有所贊助。
【IOS封裝自界說結構的辦法】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!