Skip to content

Commit 61da20c

Browse files
Merge pull request #55 from kishikawakatsumi:pintobounds
Support pinToVisibleBounds for boundary supplementary views
2 parents 55340ed + 68b290f commit 61da20c

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

IBPCollectionViewCompositionalLayout.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'IBPCollectionViewCompositionalLayout'
3-
s.version = '0.4.2'
3+
s.version = '0.5.0'
44
s.summary = 'Backport of UICollectionViewCompositionalLayout to earlier iOS 12.'
55
s.description = <<-DESC
66
A new UICollectionViewCompositionalLayout class has been added to UIKit to make it incredibly easier to create custom complex collection view layout.

IBPCollectionViewCompositionalLayout/IBPUICollectionViewCompositionalLayout.m

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
@interface IBPUICollectionViewCompositionalLayout() {
2121
NSMutableArray<UICollectionViewLayoutAttributes *> *cachedItemAttributes;
22+
NSMutableDictionary *cachedSupplementaryAttributes;
23+
NSMutableDictionary *cachedDecorationAttributes;
24+
NSMutableArray<UICollectionViewLayoutAttributes *> *layoutAttributesForPinnedSupplementaryItems;
2225

2326
CGRect contentFrame;
2427
NSMutableDictionary<NSNumber *, IBPCollectionViewOrthogonalScrollerSectionController *> *orthogonalScrollerSectionControllers;
@@ -31,6 +34,8 @@ @interface IBPUICollectionViewCompositionalLayout() {
3134

3235
@property (nonatomic) IBPUICollectionLayoutSectionOrthogonalScrollingBehavior parentCollectionViewOrthogonalScrollingBehavior;
3336

37+
@property (nonatomic) BOOL hasPinnedSupplementaryItems;
38+
3439
@end
3540

3641
@implementation IBPUICollectionViewCompositionalLayout
@@ -85,6 +90,7 @@ - (instancetype)initWithSectionProvider:(IBPUICollectionViewCompositionalLayoutS
8590

8691
- (void)commonInit {
8792
cachedItemAttributes = [[NSMutableArray alloc] init];
93+
layoutAttributesForPinnedSupplementaryItems = [[NSMutableArray alloc] init];
8894
orthogonalScrollerSectionControllers = [[NSMutableDictionary alloc] init];
8995
}
9096

@@ -101,6 +107,8 @@ - (void)prepareLayout {
101107
}
102108

103109
[cachedItemAttributes removeAllObjects];
110+
[layoutAttributesForPinnedSupplementaryItems removeAllObjects];
111+
self.hasPinnedSupplementaryItems = NO;
104112

105113
[[orthogonalScrollerSectionControllers allValues] makeObjectsPerformSelector:@selector(removeFromSuperview)];
106114
[orthogonalScrollerSectionControllers removeAllObjects];
@@ -109,13 +117,6 @@ - (void)prepareLayout {
109117
if (@available(iOS 11.0, *)) {
110118
if ([collectionView respondsToSelector:@selector(safeAreaInsets)]) {
111119
collectionContentInset = collectionView.safeAreaInsets;
112-
113-
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
114-
CGPoint contentOffset = CGPointZero;
115-
contentOffset.x = -collectionContentInset.left;
116-
contentOffset.y = -collectionContentInset.top;
117-
collectionView.contentOffset = contentOffset;
118-
}
119120
}
120121
}
121122

@@ -411,6 +412,11 @@ - (void)prepareLayout {
411412
contentFrame = CGRectUnion(contentFrame, layoutAttributes.frame);
412413
}
413414
}
415+
416+
if (boundaryItem.pinToVisibleBounds) {
417+
self.hasPinnedSupplementaryItems = YES;
418+
[layoutAttributesForPinnedSupplementaryItems addObject:layoutAttributes];
419+
}
414420
}
415421
}
416422
}
@@ -466,7 +472,7 @@ - (UICollectionViewLayoutAttributes *)prepareLayoutForBoundaryItem:(IBPNSCollect
466472
}
467473

468474
layoutAttributes.frame = itemFrame;
469-
layoutAttributes.zIndex = layoutAttributes.zIndex;
475+
layoutAttributes.zIndex = boundaryItem.zIndex;
470476

471477
return layoutAttributes;
472478
}
@@ -481,6 +487,9 @@ - (CGSize)collectionViewContentSize {
481487

482488
for (NSInteger i = 0; i < cachedItemAttributes.count; i++) {
483489
UICollectionViewLayoutAttributes *attributes = cachedItemAttributes[i];
490+
if (!CGRectIntersectsRect(attributes.frame, rect)) {
491+
continue;
492+
}
484493

485494
NSIndexPath *indexPath = attributes.indexPath;
486495
IBPNSCollectionLayoutItem *layoutItem = [solver layoutItemAtIndexPath:indexPath];
@@ -535,15 +544,48 @@ - (CGSize)collectionViewContentSize {
535544
contentFrame = CGRectUnion(contentFrame, f);
536545

537546
[layoutAttributes addObject:attributes];
538-
} else {
539-
[layoutAttributes addObject:attributes];
547+
continue;
548+
}
549+
}
550+
}
551+
552+
[layoutAttributes addObject:attributes];
553+
}
554+
555+
for (NSInteger i = 0; i < layoutAttributesForPinnedSupplementaryItems.count; i++) {
556+
CGPoint contentOffset = self.collectionView.contentOffset;
557+
UICollectionViewLayoutAttributes *attributes = layoutAttributesForPinnedSupplementaryItems[i];
558+
if (!CGRectIntersectsRect(attributes.frame, rect)) {
559+
continue;
560+
}
561+
562+
if (@available(iOS 11.0, *)) {
563+
if ([self.collectionView respondsToSelector:@selector(safeAreaInsets)]) {
564+
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
565+
contentOffset.y += self.collectionView.safeAreaInsets.top;
566+
}
567+
if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
568+
contentOffset.x += self.collectionView.safeAreaInsets.left;
540569
}
541-
} else {
542-
[layoutAttributes addObject:attributes];
543570
}
544-
} else {
545-
[layoutAttributes addObject:attributes];
546571
}
572+
573+
CGPoint nextHeaderOrigin = CGPointMake(INFINITY, INFINITY);
574+
575+
if (i + 1 < layoutAttributesForPinnedSupplementaryItems.count) {
576+
UICollectionViewLayoutAttributes *nextHeaderAttributes = layoutAttributesForPinnedSupplementaryItems[i + 1];
577+
nextHeaderOrigin = nextHeaderAttributes.frame.origin;
578+
}
579+
580+
CGRect frame = attributes.frame;
581+
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
582+
frame.origin.y = MIN(MAX(contentOffset.y, frame.origin.y), nextHeaderOrigin.y - CGRectGetHeight(frame));
583+
}
584+
if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
585+
frame.origin.x = MIN(MAX(contentOffset.x, frame.origin.x), nextHeaderOrigin.x - CGRectGetWidth(frame));
586+
}
587+
588+
attributes.frame = frame;
547589
}
548590

549591
return layoutAttributes;
@@ -553,6 +595,9 @@ - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
553595
if (!self.collectionView) {
554596
return NO;
555597
}
598+
if (self.hasPinnedSupplementaryItems) {
599+
return YES;
600+
}
556601

557602
return !CGSizeEqualToSize(newBounds.size, self.collectionView.bounds.size);
558603
}

IBPCollectionViewCompositionalLayout/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>0.4.2</string>
18+
<string>0.5.0</string>
1919
<key>CFBundleVersion</key>
2020
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
</dict>

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ This file silences the following compilation errors when building on Xcode 11 or
9696
- [x] Inter Section Spacing
9797
- [x] Scroll Direction
9898
- [x] Nested Groups
99-
- [x] Section Header/Footers (Partially supported)
99+
- [x] Section Header/Footers
100+
- [x] Pinned Section Header/Footers
100101
- [x] Decoration Views
101102
- [x] Orthogonal Scrolling
102103
- [x] Orthogonal Scrolling Behavior
@@ -105,7 +106,6 @@ This file silences the following compilation errors when building on Xcode 11 or
105106

106107
## TODOs (Not yet supported)
107108

108-
- [ ] Pinned Section Header/Footers
109109
- [ ] Flexible Spaces
110110
- [ ] RTL Support
111111
- [ ] Custom Group Item (Absolute Positions)

0 commit comments

Comments
 (0)