CGXVerticalMenuRoundFlowLayout.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. //
  2. // CGXVerticalMenuRoundFlowLayout.m
  3. // CGXVerticalMenuView-OC
  4. //
  5. // Created by CGX on 2018/05/01.
  6. // Copyright © 2019 CGX. All rights reserved.
  7. //
  8. #import "CGXVerticalMenuRoundFlowLayout.h"
  9. #import "CGXVerticalMenuRoundFlowLayoutUtils.h"
  10. static NSString *const CGXVerticalMenuRoundFlowLayoutRoundSection = @"com.CGXVerticalMenuRoundFlowLayoutRoundSection";
  11. @interface CGXVerticalMenuRoundFlowLayout ()
  12. @property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *decorationViewAttrs;
  13. @property (nonatomic, strong,readwrite) NSArray <UICollectionViewLayoutAttributes *> *sectionHeaderAttributes;
  14. @end
  15. @implementation CGXVerticalMenuRoundFlowLayout
  16. - (instancetype)init{
  17. self = [super init];
  18. if (self) {
  19. self.isRoundEnabled = YES;
  20. }
  21. return self;
  22. }
  23. - (void)awakeFromNib{
  24. [super awakeFromNib];
  25. _isRoundEnabled = YES;
  26. }
  27. - (void)prepareLayout{
  28. [super prepareLayout];
  29. if (!self.isRoundEnabled) {
  30. return;
  31. }
  32. NSInteger sections = [self.collectionView numberOfSections];
  33. id <CGXVerticalMenuRoundFlowLayoutDelegate> delegate = (id <CGXVerticalMenuRoundFlowLayoutDelegate>)self.collectionView.delegate;
  34. // id delegate = self.collectionView.delegate;
  35. //检测是否实现了背景样式模块代理
  36. if ([delegate respondsToSelector:@selector(collectionView:configModelForSectionAtIndex:)]) {
  37. }else{
  38. return ;
  39. }
  40. //1.初始化
  41. [self registerClass:[CGXVerticalMenuRoundReusableView class] forDecorationViewOfKind:CGXVerticalMenuRoundFlowLayoutRoundSection];
  42. [self.decorationViewAttrs removeAllObjects];
  43. for (NSInteger section = 0; section < sections; section++) {
  44. NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
  45. if (numberOfItems > 0) {
  46. UICollectionViewLayoutAttributes *firstAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  47. CGRect firstFrame = firstAttr.frame;
  48. //headerView
  49. UICollectionViewLayoutAttributes *headerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  50. //footerView
  51. UICollectionViewLayoutAttributes *footerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  52. // 最后一个item
  53. UICollectionViewLayoutAttributes *lastAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:(numberOfItems - 1) inSection:section]];
  54. CGRect lastFrame = lastAttr.frame;
  55. BOOL isHeaderAttr = (headerAttr &&
  56. (headerAttr.frame.size.width != 0 && headerAttr.frame.size.height != 0));
  57. BOOL isFooterAttr = (footerAttr &&
  58. (footerAttr.frame.size.width != 0 && footerAttr.frame.size.height != 0));
  59. //判断是否计算headerview
  60. BOOL isCalculateHeaderView = [self isCalculateHeaderViewSection:section] && isHeaderAttr;
  61. //判断是否计算footerView
  62. BOOL isCalculateFooterView = [self isCalculateFooterViewSection:section] && isFooterAttr;
  63. firstFrame = [self calculateDefaultFrameWithFirstHeader:isCalculateHeaderView Section:section NumberOfItems:numberOfItems IsOpen:self.isCalculateOpenIrregularCell];
  64. lastFrame = [self calculateDefaultFrameWithFirstFooter:isCalculateFooterView Section:section NumberOfItems:numberOfItems IsOpen:self.isCalculateOpenIrregularCell];
  65. //获取sectionInset
  66. UIEdgeInsets sectionInset = [CGXVerticalMenuRoundFlowLayoutUtils evaluatedSectionInsetForItemWithCollectionLayout:self atIndex:section];
  67. CGRect sectionFrame = CGRectUnion(firstFrame, lastFrame);
  68. if (!isCalculateHeaderView && !isCalculateFooterView) {
  69. //都没有headerView&footerView
  70. sectionFrame = [self calculateDefaultFrameWithSectionFrame:sectionFrame sectionInset:sectionInset];
  71. }else{
  72. if (isCalculateHeaderView && !isCalculateFooterView) {
  73. //判断是否有headerview
  74. if (isHeaderAttr) {
  75. //判断包含headerview, top位置已经计算在内,不需要补偏移
  76. sectionFrame.size.height += sectionInset.bottom;
  77. }else{
  78. sectionFrame = [self calculateDefaultFrameWithSectionFrame:sectionFrame sectionInset:sectionInset];
  79. }
  80. }else if (!isCalculateHeaderView && isCalculateFooterView) {
  81. if (isFooterAttr) {
  82. //判断包含footerView, bottom位置已经计算在内,不需要补偏移
  83. //(需要补充y偏移)
  84. sectionFrame.origin.y -= sectionInset.top;
  85. sectionFrame.size.width = self.collectionView.frame.size.width;
  86. sectionFrame.size.height += sectionInset.top;
  87. }else{
  88. sectionFrame = [self calculateDefaultFrameWithSectionFrame:sectionFrame sectionInset:sectionInset];
  89. }
  90. }else{
  91. if (isHeaderAttr && isFooterAttr) {
  92. //都有headerview和footerview就不用计算了
  93. }else{
  94. sectionFrame = [self calculateDefaultFrameWithSectionFrame:sectionFrame sectionInset:sectionInset];
  95. }
  96. }
  97. }
  98. UIEdgeInsets userCustomSectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
  99. if ([delegate respondsToSelector:@selector(collectionView:borderEdgeInsertsForSectionAtIndex:)]) {
  100. //检测是否实现了该方法,进行赋值
  101. userCustomSectionInset = [delegate collectionView:self.collectionView borderEdgeInsertsForSectionAtIndex:section];
  102. }
  103. sectionFrame.origin.x += userCustomSectionInset.left;
  104. sectionFrame.origin.y += userCustomSectionInset.top;
  105. if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
  106. sectionFrame.size.width -= (userCustomSectionInset.left + userCustomSectionInset.right);
  107. sectionFrame.size.height -= (userCustomSectionInset.top + userCustomSectionInset.bottom);
  108. }else{
  109. sectionFrame.size.width -= (userCustomSectionInset.left + userCustomSectionInset.right);
  110. sectionFrame.size.height -= (userCustomSectionInset.top + userCustomSectionInset.bottom);
  111. }
  112. //2. 定义
  113. CGXVerticalMenuRoundLayoutAttributes *attr = [CGXVerticalMenuRoundLayoutAttributes layoutAttributesForDecorationViewOfKind:CGXVerticalMenuRoundFlowLayoutRoundSection withIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  114. attr.frame = sectionFrame;
  115. attr.zIndex = -1;
  116. attr.borderEdgeInsets = userCustomSectionInset;
  117. if ([delegate respondsToSelector:@selector(collectionView:configModelForSectionAtIndex:)]) {
  118. attr.myConfigModel = [delegate collectionView:self.collectionView configModelForSectionAtIndex:section];
  119. }
  120. [self.decorationViewAttrs addObject:attr];
  121. }else{
  122. continue ;
  123. }
  124. }
  125. if (sections>0) {
  126. if (self.sectionHeaderAttributes == nil) {
  127. //获取到所有的sectionHeaderAtrributes,用于后续的点击,滚动到指定contentOffset.y使用
  128. NSMutableArray *attributes = [NSMutableArray array];
  129. UICollectionViewLayoutAttributes *lastHeaderAttri = nil;
  130. for (int i = 0; i < sections; i++) {
  131. UICollectionViewLayoutAttributes *attri = [self.collectionView.collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:i]];
  132. if (attri) {
  133. [attributes addObject:attri];
  134. }
  135. if (i == sections - 1) {
  136. lastHeaderAttri = attri;
  137. }
  138. }
  139. if (attributes.count == 0) {
  140. return;
  141. }
  142. self.sectionHeaderAttributes = attributes;
  143. // NSInteger rowCount = [self.collectionView numberOfItemsInSection:sections-1];
  144. // //如果最后一个section条目太少了,会导致滚动最底部,但是却不能触发categoryView选中最后一个item。而且点击最后一个滚动的contentOffset.y也不好弄。所以添加contentInset,让最后一个section滚到最下面能显示完整个屏幕。
  145. // UICollectionViewLayoutAttributes *lastCellAttri = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:rowCount inSection:sections-1]];
  146. // CGFloat lastSectionHeight = CGRectGetMaxY(lastCellAttri.frame) - CGRectGetMinY(lastHeaderAttri.frame);
  147. // CGFloat value = self.collectionView.bounds.size.height - lastSectionHeight;
  148. // if (value > 0) {
  149. // self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, value+20, 0);
  150. // }
  151. }
  152. }
  153. }
  154. - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
  155. NSMutableArray * attrs = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
  156. for (UICollectionViewLayoutAttributes *attr in self.decorationViewAttrs) {
  157. [attrs addObject:attr];
  158. }
  159. [self layoutHeaderFooterAttributesForElementsInRect:rect attributes:attrs];
  160. return attrs;
  161. }
  162. //return YES;表示一旦滑动就实时调用上面这个layoutAttributesForElementsInRect:方法
  163. - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
  164. {
  165. return YES;
  166. }
  167. - (void)layoutHeaderFooterAttributesForElementsInRect:(CGRect)rect attributes:(NSMutableArray *)superAttributes
  168. {
  169. NSMutableIndexSet *noneHeaderSections = [NSMutableIndexSet indexSet];
  170. for (UICollectionViewLayoutAttributes *attributes in superAttributes)
  171. {
  172. if (attributes.representedElementCategory == UICollectionElementCategoryCell)
  173. {
  174. [noneHeaderSections addIndex:attributes.indexPath.section];
  175. }
  176. }
  177. for (UICollectionViewLayoutAttributes *attributes in superAttributes)
  178. {
  179. if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader])
  180. {
  181. [noneHeaderSections removeIndex:attributes.indexPath.section];
  182. }
  183. }
  184. [noneHeaderSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop){
  185. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
  186. UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
  187. if (attributes)
  188. {
  189. [superAttributes addObject:attributes];
  190. }
  191. }];
  192. id <CGXVerticalMenuRoundFlowLayoutDelegate> delegate = (id <CGXVerticalMenuRoundFlowLayoutDelegate>)self.collectionView.delegate;
  193. for (UICollectionViewLayoutAttributes *attributes in superAttributes) {
  194. BOOL sectionHeaderViewHovering = NO;
  195. if (delegate && [delegate respondsToSelector:@selector(collectionView:sectionHeadersPinAtSection:)]) {
  196. sectionHeaderViewHovering = [delegate collectionView:self.collectionView sectionHeadersPinAtSection:attributes.indexPath.section];
  197. }
  198. CGFloat sectionHeaderViewHoveringTopEdging = 0;
  199. if (delegate && [delegate respondsToSelector:@selector(collectionView:sectionHeadersPinTopSpaceAtSection:)]) {
  200. sectionHeaderViewHoveringTopEdging = [delegate collectionView:self.collectionView sectionHeadersPinTopSpaceAtSection:attributes.indexPath.section];
  201. }
  202. UIEdgeInsets sectionInset = [self gx_insetForSectionAtIndex:attributes.indexPath.section];
  203. if (sectionHeaderViewHovering) {
  204. if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]){
  205. NSInteger numberOfItemsInSection = [self.collectionView numberOfItemsInSection:attributes.indexPath.section];
  206. NSIndexPath *firstItemIndexPath = [NSIndexPath indexPathForItem:0 inSection:attributes.indexPath.section];
  207. NSIndexPath *lastItemIndexPath = [NSIndexPath indexPathForItem:MAX(0, numberOfItemsInSection-1) inSection:attributes.indexPath.section];
  208. UICollectionViewLayoutAttributes *firstItemAttributes, *lastItemAttributes;
  209. if (numberOfItemsInSection>0){
  210. firstItemAttributes = [self layoutAttributesForItemAtIndexPath:firstItemIndexPath];
  211. lastItemAttributes = [self layoutAttributesForItemAtIndexPath:lastItemIndexPath];
  212. }else{
  213. firstItemAttributes = [UICollectionViewLayoutAttributes new];
  214. CGFloat y = CGRectGetMaxY(attributes.frame)+self.sectionInset.top;
  215. firstItemAttributes.frame = CGRectMake(0, y, 0, 0);
  216. lastItemAttributes = firstItemAttributes;
  217. }
  218. CGRect rect = attributes.frame;
  219. CGFloat offset = self.collectionView.contentOffset.y + sectionHeaderViewHoveringTopEdging;
  220. CGFloat headerY = firstItemAttributes.frame.origin.y - rect.size.height - sectionInset.top;
  221. CGFloat maxY = MAX(offset,headerY);
  222. CGFloat headerMissingY = CGRectGetMaxY(lastItemAttributes.frame) + sectionInset.bottom - rect.size.height;
  223. rect.origin.y = MIN(maxY,headerMissingY);
  224. attributes.frame = rect;
  225. attributes.zIndex = 1;
  226. }
  227. }
  228. }
  229. }
  230. //判断是否计算headerview
  231. - (BOOL)isCalculateHeaderViewSection:(NSInteger)section
  232. {
  233. BOOL isCalculateHeaderView = NO;
  234. id <CGXVerticalMenuRoundFlowLayoutDelegate> delegate = (id <CGXVerticalMenuRoundFlowLayoutDelegate>)self.collectionView.delegate;
  235. if ([delegate respondsToSelector:@selector(collectionView:isCalculateHeaderViewIndex:)]) {
  236. isCalculateHeaderView = [delegate collectionView:self.collectionView isCalculateHeaderViewIndex:section];
  237. }else{
  238. isCalculateHeaderView = self.isCalculateHeader;
  239. }
  240. return isCalculateHeaderView;
  241. }
  242. //判断是否计算footerView
  243. - (BOOL)isCalculateFooterViewSection:(NSInteger)section
  244. {
  245. BOOL isCalculateFooterView = NO;
  246. id <CGXVerticalMenuRoundFlowLayoutDelegate> delegate = (id <CGXVerticalMenuRoundFlowLayoutDelegate>)self.collectionView.delegate;
  247. if ([delegate respondsToSelector:@selector(collectionView:isCalculateFooterViewIndex:)]) {
  248. isCalculateFooterView = [delegate collectionView:self.collectionView isCalculateFooterViewIndex:section];
  249. }else{
  250. isCalculateFooterView = self.isCalculateFooter;
  251. }
  252. return isCalculateFooterView;
  253. }
  254. /// 计算默认不包含headerview和footerview的背景大小
  255. /// @param frame frame description
  256. /// @param sectionInset sectionInset description
  257. - (CGRect)calculateDefaultFrameWithSectionFrame:(CGRect)frame sectionInset:(UIEdgeInsets)sectionInset{
  258. CGRect sectionFrame = frame;
  259. sectionFrame.origin.x -= sectionInset.left;
  260. sectionFrame.origin.y -= sectionInset.top;
  261. if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
  262. sectionFrame.size.width += sectionInset.left + sectionInset.right;
  263. //减去系统adjustInset的top
  264. if (@available(iOS 11.0, *)) {
  265. sectionFrame.size.height = self.collectionView.frame.size.height - self.collectionView.adjustedContentInset.top;
  266. } else {
  267. sectionFrame.size.height = self.collectionView.frame.size.height - fabs(self.collectionView.contentOffset.y)/*适配iOS11以下*/;
  268. }
  269. }else{
  270. sectionFrame.size.width = self.collectionView.frame.size.width;
  271. sectionFrame.size.height += sectionInset.top + sectionInset.bottom;
  272. }
  273. return sectionFrame;
  274. }
  275. /// 计算headerview背景大小
  276. /// @param isCalculateHeaderView 是否计算头
  277. /// @param section 分区
  278. /// @param numberOfItems 第几个
  279. /// @param isOpen 是否打开不规则运算
  280. - (CGRect)calculateDefaultFrameWithFirstHeader:(BOOL)isCalculateHeaderView
  281. Section:(NSInteger)section
  282. NumberOfItems:(NSInteger)numberOfItems
  283. IsOpen:(BOOL)isOpen
  284. {
  285. BOOL isCalculateOpenIrregularCell = isOpen;
  286. // 第一个item
  287. UICollectionViewLayoutAttributes *firstAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  288. //headerView
  289. UICollectionViewLayoutAttributes *headerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  290. CGRect firstFrame = firstAttr.frame;
  291. if (isCalculateHeaderView) {
  292. if (headerAttr &&
  293. (headerAttr.frame.size.width != 0 && headerAttr.frame.size.height != 0)) {
  294. firstFrame = headerAttr.frame;
  295. }else{
  296. CGRect rect = firstFrame;
  297. if (isCalculateOpenIrregularCell) {
  298. rect = [CGXVerticalMenuRoundFlowLayoutUtils calculateIrregularitiesCellByMinTopFrameWithLayout:self section:section numberOfItems:numberOfItems defaultFrame:rect];
  299. }
  300. firstFrame = CGRectMake(rect.origin.x, rect.origin.y, self.collectionView.bounds.size.width, rect.size.height);
  301. }
  302. }else{
  303. //不计算headerview的情况
  304. if (isCalculateOpenIrregularCell) {
  305. firstFrame = [CGXVerticalMenuRoundFlowLayoutUtils calculateIrregularitiesCellByMinTopFrameWithLayout:self section:section numberOfItems:numberOfItems defaultFrame:firstFrame];
  306. }
  307. }
  308. return firstFrame;
  309. }
  310. /// 计算footerview的背景大小
  311. /// @param isCalculateFooterView 是否计算脚
  312. /// @param section 分区
  313. /// @param numberOfItems 第几个
  314. /// @param isOpen 是否打开不规则运算
  315. - (CGRect)calculateDefaultFrameWithFirstFooter:(BOOL)isCalculateFooterView
  316. Section:(NSInteger)section
  317. NumberOfItems:(NSInteger)numberOfItems
  318. IsOpen:(BOOL)isOpen
  319. {
  320. BOOL isCalculateOpenIrregularCell = isOpen;
  321. // 最后一个item
  322. UICollectionViewLayoutAttributes *lastAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:(numberOfItems - 1) inSection:section]];
  323. //footerView
  324. UICollectionViewLayoutAttributes *footerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
  325. CGRect lastFrame = lastAttr.frame;
  326. if (isCalculateFooterView) {
  327. if (footerAttr &&
  328. (footerAttr.frame.size.width != 0 && footerAttr.frame.size.height != 0)) {
  329. lastFrame = footerAttr.frame;
  330. }else{
  331. CGRect rect = lastFrame;
  332. if (isCalculateOpenIrregularCell) {
  333. rect = [CGXVerticalMenuRoundFlowLayoutUtils calculateIrregularitiesCellByMaxBottomFrameWithLayout:self section:section numberOfItems:numberOfItems defaultFrame:rect];
  334. }
  335. lastFrame = CGRectMake(rect.origin.x, rect.origin.y, self.collectionView.bounds.size.width, rect.size.height);
  336. }
  337. }else{
  338. //不计算footerView的情况
  339. if (isCalculateOpenIrregularCell) {
  340. lastFrame = [CGXVerticalMenuRoundFlowLayoutUtils calculateIrregularitiesCellByMaxBottomFrameWithLayout:self section:section numberOfItems:numberOfItems defaultFrame:lastFrame];
  341. }
  342. }
  343. return lastFrame;
  344. }
  345. #pragma mark - other
  346. - (NSMutableArray<UICollectionViewLayoutAttributes *> *)decorationViewAttrs{
  347. if (!_decorationViewAttrs) {
  348. _decorationViewAttrs = [NSMutableArray array];
  349. }
  350. return _decorationViewAttrs;
  351. }
  352. - (CGFloat)gx_minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
  353. {
  354. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
  355. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  356. return [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
  357. } else {
  358. return self.minimumInteritemSpacing;
  359. }
  360. }
  361. - (CGFloat)gx_minimumLineSpacingForSectionAtIndex:(NSInteger)section
  362. {
  363. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
  364. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  365. return [delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
  366. } else {
  367. return self.minimumLineSpacing;
  368. }
  369. }
  370. - (CGSize)gx_referenceSizeForHeaderInSection:(NSInteger)section
  371. {
  372. CGSize size = CGSizeMake(0, 0);
  373. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)]) {
  374. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  375. size = [delegate collectionView:self.collectionView layout:self referenceSizeForHeaderInSection:section];
  376. } else{
  377. size = self.headerReferenceSize;
  378. }
  379. return size;
  380. }
  381. - (CGSize)gx_referenceSizeForFooterInSection:(NSInteger)section
  382. {
  383. CGSize size = CGSizeMake(0, 0);
  384. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)]) {
  385. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  386. size = [delegate collectionView:self.collectionView layout:self referenceSizeForFooterInSection:section];
  387. } else{
  388. size = self.footerReferenceSize;
  389. }
  390. return size;
  391. }
  392. - (UIEdgeInsets)gx_insetForSectionAtIndex:(NSInteger)section
  393. {
  394. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
  395. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  396. return [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
  397. } else {
  398. return self.sectionInset;
  399. }
  400. }
  401. - (CGSize)gx_sizeForItemAtIndexPath:(NSIndexPath *)indexPath
  402. {
  403. if (self.collectionView.delegate && [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
  404. id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
  405. return [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
  406. } else {
  407. return self.itemSize;
  408. }
  409. }
  410. @end