Skip to content

Commit 2251443

Browse files
Merge pull request #106 from kishikawakatsumi/edge-spacing
Support layout item edge spacing
2 parents 016d775 + 70ec7d9 commit 2251443

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

Sources/IBPCollectionViewCompositionalLayout/IBPCollectionCompositionalLayoutSolver.m

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#import "IBPCollectionCompositionalLayoutSolverResult.h"
33
#import "IBPNSCollectionLayoutContainer.h"
44
#import "IBPNSCollectionLayoutDimension.h"
5+
#import "IBPNSCollectionLayoutEdgeSpacing_Private.h"
56
#import "IBPNSCollectionLayoutEnvironment.h"
67
#import "IBPNSCollectionLayoutGroup_Private.h"
78
#import "IBPNSCollectionLayoutItem_Private.h"
@@ -169,6 +170,9 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
169170
[group enumerateItemsWithHandler:^(IBPNSCollectionLayoutItem * _Nonnull item, BOOL * _Nonnull stop) {
170171
IBPNSDirectionalEdgeInsets contentInsets = item.contentInsets;
171172

173+
contentFrame.origin.x += item.edgeSpacing.leading.spacing;
174+
contentFrame.origin.y += item.edgeSpacing.top.spacing;
175+
172176
CGSize itemSize = [item.layoutSize effectiveSizeForContainer:container];
173177
IBPNSCollectionLayoutContainer *itemContainer = [[IBPNSCollectionLayoutContainer alloc] initWithContentSize:itemSize contentInsets:item.contentInsets];
174178

@@ -200,14 +204,14 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
200204
*stop = YES;
201205
return;
202206
}
203-
contentFrame.origin.x += itemSize.width;
207+
contentFrame.origin.x += itemSize.width + item.edgeSpacing.trailing.spacing;
204208
}
205209
if (group.isVerticalGroup) {
206210
if (floor(CGRectGetMaxY(contentFrame)) > floor(CGRectGetMaxY(containerFrame))) {
207211
*stop = YES;
208212
return;
209213
}
210-
contentFrame.origin.y += itemSize.height;
214+
contentFrame.origin.y += itemSize.height + item.edgeSpacing.bottom.spacing;
211215
}
212216

213217
if (group == self.layoutSection.group) {
@@ -228,7 +232,7 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
228232

229233
contentFrame.size = itemSize;
230234
if (group.isHorizontalGroup) {
231-
if (floor(CGRectGetMaxX(contentFrame)) > floor(CGRectGetMaxX(containerFrame))) {
235+
if (floor(CGRectGetMaxX(contentFrame)) + item.edgeSpacing.trailing.spacing > floor(CGRectGetMaxX(containerFrame))) {
232236
*stop = YES;
233237
return;
234238
}
@@ -237,10 +241,10 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
237241
IBPCollectionCompositionalLayoutSolverResult *result = [IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame];
238242
[self.results addObject:result];
239243
[groupedItemResults addObject:result];
240-
contentFrame.origin.x += CGRectGetWidth(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing;
244+
contentFrame.origin.x += CGRectGetWidth(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing + item.edgeSpacing.trailing.spacing;
241245
}
242246
if (group.isVerticalGroup) {
243-
if (floor(CGRectGetMaxY(contentFrame)) > floor(CGRectGetMaxY(containerFrame))) {
247+
if (floor(CGRectGetMaxY(contentFrame) + item.edgeSpacing.bottom.spacing) > floor(CGRectGetMaxY(containerFrame))) {
244248
*stop = YES;
245249
return;
246250
}
@@ -249,10 +253,78 @@ - (void)solveGroup:(IBPNSCollectionLayoutGroup *)group forContainer:(IBPNSCollec
249253
IBPCollectionCompositionalLayoutSolverResult *result = [IBPCollectionCompositionalLayoutSolverResult resultWithLayoutItem:item frame:cellFrame];
250254
[self.results addObject:result];
251255
[groupedItemResults addObject:result];
252-
contentFrame.origin.y += CGRectGetHeight(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing;
256+
contentFrame.origin.y += CGRectGetHeight(contentFrame) + interItemFixedSpacing + interItemFlexibleSpacing + item.edgeSpacing.bottom.spacing;
253257
}
254258
}];
255-
if (interItemFlexibleSpacing > 0 && groupedItemResults.count > 1) {
259+
260+
if (groupedItemResults.count > 0) {
261+
CGSize totalSize = CGSizeZero;
262+
NSInteger horizontalFlexibleSpacingCount = 0;
263+
NSInteger verticalFlexibleSpacingCount = 0;
264+
for (IBPCollectionCompositionalLayoutSolverResult *result in groupedItemResults) {
265+
totalSize.width += CGRectGetWidth(result.frame);
266+
totalSize.height += CGRectGetHeight(result.frame);
267+
268+
IBPNSCollectionLayoutItem *item = result.layoutItem;
269+
IBPNSCollectionLayoutEdgeSpacing *edgeSpacing = item.edgeSpacing;
270+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeLeading]) {
271+
horizontalFlexibleSpacingCount++;
272+
}
273+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeTrailing]) {
274+
horizontalFlexibleSpacingCount++;
275+
}
276+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeTop]) {
277+
verticalFlexibleSpacingCount++;
278+
}
279+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeBottom]) {
280+
verticalFlexibleSpacingCount++;
281+
}
282+
}
283+
if (group.isHorizontalGroup) {
284+
CGFloat actualSpacing = floor((CGRectGetWidth(containerFrame) - totalSize.width) / horizontalFlexibleSpacingCount);
285+
CGFloat trailingDelta = 0;
286+
for (IBPCollectionCompositionalLayoutSolverResult *result in groupedItemResults) {
287+
IBPNSCollectionLayoutItem *item = result.layoutItem;
288+
IBPNSCollectionLayoutEdgeSpacing *edgeSpacing = item.edgeSpacing;
289+
290+
CGRect frame = result.frame;
291+
frame.origin.x += trailingDelta;
292+
293+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeLeading]) {
294+
CGFloat delta = floor(actualSpacing - edgeSpacing.leading.spacing);
295+
frame.origin.x += delta;
296+
trailingDelta += delta;
297+
}
298+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeTrailing]) {
299+
trailingDelta += floor(actualSpacing - edgeSpacing.trailing.spacing);
300+
}
301+
result.frame = frame;
302+
}
303+
}
304+
if (group.isVerticalGroup) {
305+
CGFloat actualSpacing = floor((CGRectGetHeight(containerFrame) - totalSize.height) / verticalFlexibleSpacingCount);
306+
CGFloat bottomDelta = 0;
307+
for (IBPCollectionCompositionalLayoutSolverResult *result in groupedItemResults) {
308+
IBPNSCollectionLayoutItem *item = result.layoutItem;
309+
IBPNSCollectionLayoutEdgeSpacing *edgeSpacing = item.edgeSpacing;
310+
311+
CGRect frame = result.frame;
312+
frame.origin.y += bottomDelta;
313+
314+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeTop]) {
315+
CGFloat delta = floor(actualSpacing - edgeSpacing.top.spacing);
316+
frame.origin.y += delta;
317+
bottomDelta += delta;
318+
}
319+
if ([edgeSpacing isSpacingFlexibleForEdge:IBPNSDirectionalRectEdgeBottom]) {
320+
bottomDelta += floor(actualSpacing - edgeSpacing.bottom.spacing);
321+
}
322+
result.frame = frame;
323+
}
324+
}
325+
}
326+
327+
if (interItemFlexibleSpacing > 0 && groupedItemResults.count > 1) {
256328
CGSize totalSize = CGSizeZero;
257329
for (IBPCollectionCompositionalLayoutSolverResult *result in groupedItemResults) {
258330
totalSize.width += CGRectGetWidth(result.frame);

Sources/IBPCollectionViewCompositionalLayout/IBPNSCollectionLayoutEdgeSpacing.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ - (CGFloat)spacingForEdge:(IBPNSDirectionalRectEdge)edge {
7575
IBPNSCollectionLayoutSpacing *laoutSpacing = [self _spacingForEdge:edge];
7676
return laoutSpacing.spacing;
7777
}
78+
7879
- (IBPNSCollectionLayoutSpacing *)_spacingForEdge:(IBPNSDirectionalRectEdge)edge {
7980
if (edge == IBPNSDirectionalRectEdgeLeading) {
8081
return self.leading;

Sources/IBPCollectionViewCompositionalLayout/IBPUICollectionViewCompositionalLayout.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#import "IBPNSCollectionLayoutContainer.h"
88
#import "IBPNSCollectionLayoutDecorationItem.h"
99
#import "IBPNSCollectionLayoutDimension.h"
10+
#import "IBPNSCollectionLayoutEdgeSpacing_Private.h"
1011
#import "IBPNSCollectionLayoutEnvironment.h"
1112
#import "IBPNSCollectionLayoutGroup_Private.h"
1213
#import "IBPNSCollectionLayoutItem_Private.h"
@@ -628,12 +629,12 @@ - (UICollectionViewLayoutAttributes *)prepareLayoutForBoundaryItem:(IBPNSCollect
628629
switch (self.scrollDirection) {
629630
case UICollectionViewScrollDirectionVertical:
630631
if (CGRectGetMinY(nextFrame) > CGRectGetMinY(frame)) {
631-
nextFrame.origin.y += fitSize.height - CGRectGetHeight(nextFrame);
632+
nextFrame.origin.y += fitSize.height - CGRectGetHeight(nextFrame) + layoutItem.edgeSpacing.bottom.spacing;
632633
}
633634
break;
634635
case UICollectionViewScrollDirectionHorizontal:
635636
if (CGRectGetMinX(nextFrame) > CGRectGetMinX(attributes.frame)) {
636-
nextFrame.origin.x += fitSize.width - CGRectGetWidth(nextFrame);
637+
nextFrame.origin.x += fitSize.width - CGRectGetWidth(nextFrame) + layoutItem.edgeSpacing.trailing.spacing;
637638
}
638639
break;
639640
}

0 commit comments

Comments
 (0)