Skip to content

Commit d8e5778

Browse files
Merge pull request #68 from kishikawakatsumi:flexible-spacing
Support flexible spacing
2 parents 54e6a95 + d2e806e commit d8e5778

File tree

2 files changed

+58
-20
lines changed

2 files changed

+58
-20
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,24 @@ This file silences the following compilation errors when building on Xcode 11 or
9191

9292
## Features
9393

94-
- [x] Inter Item Spacing
94+
- [x] Inter Item Spacing
9595
- [x] Inter Group Spacing
9696
- [x] Inter Section Spacing
97-
- [x] Scroll Direction
98-
- [x] Nested Groups
99-
- [x] Section Header/Footers
97+
- [x] Fixed Spacing
98+
- [x] Flexible Spacing
99+
- [x] Nested Groups
100+
- [x] Vertical Scrolling
101+
- [x] Horizontal Scrolling
102+
- [x] Supplemental Views (e.g. Section Header/Footers)
100103
- [x] Pinned Section Header/Footers
101-
- [x] Decoration Views
104+
- [x] Decoration Views (e.g. Background Views)
102105
- [x] Orthogonal Scrolling
103106
- [x] Orthogonal Scrolling Behavior
104107
- [x] Estimated Size (Autosizing)
105108
- [x] Drop-in replacement
106109

107110
## TODOs (Not yet supported)
108111

109-
- [ ] Flexible Spaces
110112
- [ ] RTL Support
111113
- [ ] Custom Group Item (Absolute Positions)
112114
- [ ] Visual Debug Description

Sources/Internal/IBPCollectionCompositionalLayoutSolver.m

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
6969
CGRect layoutFrame = self.layoutFrame;
7070
__block CGRect contentFrame = self.contentFrame;
7171

72-
CGFloat interItemSpacing = 0;
72+
CGFloat interItemFixedSpacing = 0;
7373
if (group.interItemSpacing.isFixedSpacing) {
74-
interItemSpacing = group.interItemSpacing.spacing;
74+
interItemFixedSpacing = group.interItemSpacing.spacing;
75+
}
76+
CGFloat interItemFlexibleSpacing = 0;
77+
if (group.interItemSpacing.isFlexibleSpacing) {
78+
interItemFlexibleSpacing = group.interItemSpacing.spacing;
7579
}
7680

7781
if (group.count > 0) {
@@ -88,13 +92,13 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
8892
if (floor(CGRectGetMaxX(contentFrame)) > floor(CGRectGetMaxX(layoutFrame))) {
8993
return;
9094
}
91-
itemSize.width = (CGRectGetWidth(layoutFrame) - interItemSpacing * (group.count - 1)) / group.count;
95+
itemSize.width = (CGRectGetWidth(layoutFrame) - interItemFixedSpacing * (group.count - 1)) / group.count;
9296
}
9397
if (group.isVerticalGroup) {
9498
if (floor(CGRectGetMaxX(contentFrame)) > floor(CGRectGetMaxX(layoutFrame))) {
9599
return;
96100
}
97-
itemSize.height = (CGRectGetHeight(layoutFrame) - interItemSpacing * (group.count - 1)) / group.count;
101+
itemSize.height = (CGRectGetHeight(layoutFrame) - interItemFixedSpacing * (group.count - 1)) / group.count;
98102
}
99103

100104
CGRect nestedContainerFrame = layoutFrame;
@@ -106,10 +110,10 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
106110
[self solveGroup:nestedGroup forContainer:itemContainer];
107111

108112
if (group.isHorizontalGroup) {
109-
contentFrame.origin.x += interItemSpacing + itemSize.width;
113+
contentFrame.origin.x += interItemFixedSpacing + itemSize.width;
110114
}
111115
if (group.isVerticalGroup) {
112-
contentFrame.origin.y += interItemSpacing + itemSize.height;
116+
contentFrame.origin.y += interItemFixedSpacing + itemSize.height;
113117
}
114118
}
115119

@@ -121,30 +125,31 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
121125
return;
122126
}
123127

124-
itemSize.width = (CGRectGetWidth(layoutFrame) - interItemSpacing * (group.count - 1)) / group.count;
128+
itemSize.width = (CGRectGetWidth(layoutFrame) - interItemFixedSpacing * (group.count - 1)) / group.count;
125129
contentFrame.size = itemSize;
126130

127131
for (NSInteger i = 0; i < group.count; i++) {
128132
CGRect cellFrame = UIEdgeInsetsInsetRect(contentFrame, UIEdgeInsetsMake(contentInsets.top, contentInsets.leading, contentInsets.bottom, contentInsets.trailing));
129133
[self.results addObject:[IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame]];
130-
contentFrame.origin.x += interItemSpacing + CGRectGetWidth(contentFrame);
134+
contentFrame.origin.x += interItemFixedSpacing + CGRectGetWidth(contentFrame);
131135
}
132136
}
133137
if (group.isVerticalGroup) {
134138
if (floor(CGRectGetMaxY(contentFrame)) > floor(CGRectGetMaxY(layoutFrame))) {
135139
return;
136140
}
137141

138-
itemSize.height = (CGRectGetHeight(layoutFrame) - interItemSpacing * (group.count - 1)) / group.count;
142+
itemSize.height = (CGRectGetHeight(layoutFrame) - interItemFixedSpacing * (group.count - 1)) / group.count;
139143
contentFrame.size = itemSize;
140144

141145
for (NSInteger i = 0; i < group.count; i++) {
142146
CGRect cellFrame = UIEdgeInsetsInsetRect(contentFrame, UIEdgeInsetsMake(contentInsets.top, contentInsets.leading, contentInsets.bottom, contentInsets.trailing));
143147
[self.results addObject:[IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame]];
144-
contentFrame.origin.y += interItemSpacing + CGRectGetHeight(contentFrame);
148+
contentFrame.origin.y += interItemFixedSpacing + CGRectGetHeight(contentFrame);
145149
}
146150
}
147151
} else {
152+
NSMutableArray *groupedItemResults = [[NSMutableArray alloc] init];
148153
[group enumerateItemsWithHandler:^(IBPNSCollectionLayoutItem * _Nonnull item, BOOL * _Nonnull stop) {
149154
IBPNSDirectionalEdgeInsets contentInsets = item.contentInsets;
150155

@@ -213,8 +218,10 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
213218
}
214219

215220
CGRect cellFrame = UIEdgeInsetsInsetRect(contentFrame, UIEdgeInsetsMake(contentInsets.top, contentInsets.leading, contentInsets.bottom, contentInsets.trailing));
216-
[self.results addObject:[IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame]];
217-
contentFrame.origin.x += CGRectGetWidth(contentFrame);
221+
IBPCollectionCompositionalLayoutSolverResult *result = [IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame];
222+
[self.results addObject:result];
223+
[groupedItemResults addObject:result];
224+
contentFrame.origin.x += CGRectGetWidth(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing;
218225
}
219226
if (group.isVerticalGroup) {
220227
if (floor(CGRectGetMaxY(contentFrame)) > floor(CGRectGetMaxY(layoutFrame))) {
@@ -223,10 +230,39 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
223230
}
224231

225232
CGRect cellFrame = UIEdgeInsetsInsetRect(contentFrame, UIEdgeInsetsMake(contentInsets.top, contentInsets.leading, contentInsets.bottom, contentInsets.trailing));
226-
[self.results addObject:[IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame]];
227-
contentFrame.origin.y += CGRectGetHeight(contentFrame);
233+
IBPCollectionCompositionalLayoutSolverResult *result = [IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame];
234+
[self.results addObject:result];
235+
[groupedItemResults addObject:result];
236+
contentFrame.origin.y += CGRectGetHeight(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing;
228237
}
229238
}];
239+
if (interItemFlexibleSpacing > 0 && groupedItemResults.count > 1) {
240+
CGSize totalSize = CGSizeZero;
241+
for (IBPCollectionCompositionalLayoutSolverResult *result in groupedItemResults) {
242+
totalSize.width += CGRectGetWidth(result.frame);
243+
totalSize.height += CGRectGetHeight(result.frame);
244+
}
245+
if (group.isHorizontalGroup) {
246+
CGFloat actualSpacing = (CGRectGetWidth(layoutFrame) - totalSize.width) / (groupedItemResults.count - 1);
247+
CGFloat delta = floor(actualSpacing - interItemFlexibleSpacing);
248+
for (NSInteger i = 1; i < groupedItemResults.count; i++) {
249+
IBPCollectionCompositionalLayoutSolverResult *result = groupedItemResults[i];
250+
CGRect frame = result.frame;
251+
frame.origin.x += delta * i;
252+
result.frame = frame;
253+
}
254+
}
255+
if (group.isVerticalGroup) {
256+
CGFloat actualSpacing = (CGRectGetHeight(layoutFrame) - totalSize.height) / (groupedItemResults.count - 1);
257+
CGFloat delta = floor(actualSpacing - interItemFlexibleSpacing);
258+
for (NSInteger i = 1; i < groupedItemResults.count; i++) {
259+
IBPCollectionCompositionalLayoutSolverResult *result = groupedItemResults[i];
260+
CGRect frame = result.frame;
261+
frame.origin.y += delta * i;
262+
result.frame = frame;
263+
}
264+
}
265+
}
230266
}
231267
}
232268

0 commit comments

Comments
 (0)