HXPhotoViewFlowLayout.m 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // HXPhotoViewFlowLayout.m
  3. // HXPhotoPickerExample
  4. //
  5. // Created by Silence on 2017/11/15.
  6. // Copyright © 2017年 Silence. All rights reserved.
  7. //
  8. #import "HXPhotoViewFlowLayout.h"
  9. #import "HXPhotoViewController.h"
  10. @interface HXPhotoViewFlowLayout ()
  11. @property (assign, nonatomic) BOOL hasSuspension;
  12. @end
  13. @implementation HXPhotoViewFlowLayout
  14. - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
  15. NSArray *array = [super layoutAttributesForElementsInRect:rect];
  16. NSMutableArray *answer = [array mutableCopy];
  17. UICollectionView * const cv = self.collectionView;
  18. CGPoint const contentOffset = cv.contentOffset;
  19. NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
  20. for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
  21. if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) {
  22. [missingSections addIndex:layoutAttributes.indexPath.section];
  23. }
  24. }
  25. for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
  26. if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
  27. [missingSections removeIndex:layoutAttributes.indexPath.section];
  28. }
  29. }
  30. [missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
  31. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
  32. UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
  33. [answer addObject:layoutAttributes];
  34. }];
  35. for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
  36. if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
  37. NSInteger section = layoutAttributes.indexPath.section;
  38. NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section];
  39. NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
  40. NSIndexPath *lastObjectIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section];
  41. UICollectionViewLayoutAttributes *firstObjectAttrs;
  42. UICollectionViewLayoutAttributes *lastObjectAttrs;
  43. if (numberOfItemsInSection > 0) {
  44. firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath];
  45. lastObjectAttrs = [self layoutAttributesForItemAtIndexPath:lastObjectIndexPath];
  46. } else {
  47. firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:firstObjectIndexPath];
  48. lastObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:lastObjectIndexPath];
  49. }
  50. CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame);
  51. CGPoint origin = layoutAttributes.frame.origin;
  52. CGFloat topY = contentOffset.y + cv.contentInset.top;
  53. CGFloat normalY = (CGRectGetMinY(firstObjectAttrs.frame) - headerHeight);
  54. CGFloat missingY = (CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight);
  55. CGFloat max = MAX(topY, normalY);
  56. CGFloat min = MIN(max, missingY);
  57. if (topY >= normalY && topY <= missingY + headerHeight) {
  58. // if (HX_IOS9Later) {
  59. // HXPhotoViewSectionHeaderView *headerView = (HXPhotoViewSectionHeaderView *)[cv supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:layoutAttributes.indexPath];
  60. // if (headerView) {
  61. // headerView.changeState = YES;
  62. // }
  63. // }
  64. self.hasSuspension = YES;
  65. }else {
  66. // if (HX_IOS9Later) {
  67. // HXPhotoViewSectionHeaderView *headerView = (HXPhotoViewSectionHeaderView *)[cv supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:layoutAttributes.indexPath];
  68. // if (headerView) {
  69. // headerView.changeState = NO;
  70. // }
  71. // }
  72. self.hasSuspension = NO;
  73. }
  74. if (origin.y != min && self.hasSuspension) {
  75. origin.y = min;
  76. layoutAttributes.zIndex = 1024;
  77. layoutAttributes.frame = (CGRect){
  78. .origin = origin,
  79. .size = layoutAttributes.frame.size
  80. };
  81. }
  82. }
  83. }
  84. return answer;
  85. }
  86. - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
  87. return YES;
  88. }
  89. @end