-
Notifications
You must be signed in to change notification settings - Fork 2
/
PDKTStickySectionHeadersCollectionViewLayout.m
executable file
·78 lines (74 loc) · 4.31 KB
/
PDKTStickySectionHeadersCollectionViewLayout.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//
// UICollectionViewTableViewLikeFlowLayout.m
// Caoba
//
// Created by Daniel García on 26/12/13.
// Copyright (c) 2013 Produkt. All rights reserved.
//
#import "PDKTStickySectionHeadersCollectionViewLayout.h"
@implementation PDKTStickySectionHeadersCollectionViewLayout
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
NSMutableArray *visibleSectionsWithoutHeader = [NSMutableArray array];
for (UICollectionViewLayoutAttributes *itemAttributes in attributes) {
if (![visibleSectionsWithoutHeader containsObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]]) {
[visibleSectionsWithoutHeader addObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]];
}
if (itemAttributes.representedElementKind==UICollectionElementKindSectionHeader) {
NSUInteger indexOfSectionObject=[visibleSectionsWithoutHeader indexOfObject:[NSNumber numberWithInteger:itemAttributes.indexPath.section]];
if (indexOfSectionObject!=NSNotFound) {
[visibleSectionsWithoutHeader removeObjectAtIndex:indexOfSectionObject];
}
}
}
for (NSNumber *sectionNumber in visibleSectionsWithoutHeader) {
if ([self shouldStickHeaderToTopInSection:[sectionNumber integerValue]]) {
UICollectionViewLayoutAttributes *headerAttributes=[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:[sectionNumber integerValue]]];
if (headerAttributes.frame.size.width>0 && headerAttributes.frame.size.height>0) {
[attributes addObject:headerAttributes];
}
}
}
for (UICollectionViewLayoutAttributes *itemAttributes in attributes) {
if (itemAttributes.representedElementKind==UICollectionElementKindSectionHeader) {
UICollectionViewLayoutAttributes *headerAttributes = itemAttributes;
if ([self shouldStickHeaderToTopInSection:headerAttributes.indexPath.section]) {
CGPoint contentOffset = self.collectionView.contentOffset;
CGPoint originInCollectionView=CGPointMake(headerAttributes.frame.origin.x-contentOffset.x, headerAttributes.frame.origin.y-contentOffset.y);
originInCollectionView.y-=self.collectionView.contentInset.top;
CGRect frame = headerAttributes.frame;
if (originInCollectionView.y<0) {
frame.origin.y+=(originInCollectionView.y*-1);
}
NSInteger numberOfSections = 1;
if ([self.collectionView.dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) {
numberOfSections = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView];
}
if (numberOfSections>headerAttributes.indexPath.section+1) {
UICollectionViewLayoutAttributes *nextHeaderAttributes=[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:headerAttributes.indexPath.section+1]];
CGFloat maxY=nextHeaderAttributes.frame.origin.y;
if (CGRectGetMaxY(frame)>=maxY) {
frame.origin.y=maxY-frame.size.height;
}
}
headerAttributes.frame = frame;
}
headerAttributes.zIndex = 1024;
}
}
return attributes;
}
- (BOOL)shouldStickHeaderToTopInSection:(NSUInteger)section{
BOOL shouldStickToTop=YES;
if ([self.collectionView.delegate conformsToProtocol:@protocol(PDKTStickySectionHeadersCollectionViewLayoutDelegate)]) {
id<PDKTStickySectionHeadersCollectionViewLayoutDelegate> stickyHeadersDelegate=(id<PDKTStickySectionHeadersCollectionViewLayoutDelegate>)self.collectionView.delegate;
if ([stickyHeadersDelegate respondsToSelector:@selector(shouldStickHeaderToTopInSection:)]) {
shouldStickToTop=[stickyHeadersDelegate shouldStickHeaderToTopInSection:section];
}
}
return shouldStickToTop;
}
@end