//
|
// LBKeyWordLayout.m
|
// IphoneBIMe
|
//
|
// Created by ZhangJF on 2023/3/9.
|
// Copyright © 2023 ProBIM. All rights reserved.
|
//
|
#import "LBKeyWordLayout.h"
|
|
@interface LBKeyWordLayout()
|
@property (strong, nonatomic) NSCache *cache;
|
@end
|
|
@implementation LBKeyWordLayout
|
|
- (void)prepareLayout
|
{
|
[super prepareLayout];
|
self.cache = [NSCache new];
|
}
|
|
- (void)invalidateLayout
|
{
|
[super invalidateLayout];
|
self.cache = [NSCache new];
|
}
|
|
- (BOOL)shouldInvalidateLayoutForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributes
|
{
|
return YES;
|
}
|
|
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
|
{
|
return YES;
|
}
|
|
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
|
{
|
NSArray<UICollectionViewLayoutAttributes *> *attributes = [super layoutAttributesForElementsInRect:rect].copy;
|
return [self layoutAttributesForElements:attributes];
|
}
|
|
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
|
{
|
return [self attributesAtIndexPath:indexPath];
|
}
|
|
#pragma mark - Private
|
|
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElements:(NSArray<UICollectionViewLayoutAttributes *> *)attributes
|
{
|
NSMutableArray<UICollectionViewLayoutAttributes *> *alignedAttributes = [NSMutableArray new];
|
|
for (UICollectionViewLayoutAttributes *item in attributes) {
|
if(item.representedElementKind != nil) {
|
[alignedAttributes addObject:item];
|
} else {
|
[alignedAttributes addObject:[self layoutAttributesForItem:item atIndexPath:item.indexPath]];
|
}
|
}
|
|
return alignedAttributes.copy;
|
}
|
|
- (UICollectionViewLayoutAttributes *)layoutAttributesForItem:(UICollectionViewLayoutAttributes *)attributes atIndexPath:(NSIndexPath *)indexPath
|
{
|
return [self attributes:attributes atIndexPath:indexPath];
|
}
|
|
- (UICollectionViewLayoutAttributes *)attributesAtIndexPath:(NSIndexPath *)indexPath
|
{
|
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath].copy;
|
return [self attributes:attributes atIndexPath:indexPath];
|
}
|
|
- (UICollectionViewLayoutAttributes *)attributes:(UICollectionViewLayoutAttributes *)attributes atIndexPath:(NSIndexPath *)indexPath
|
{
|
if ([self.cache objectForKey:indexPath]) {
|
return [self.cache objectForKey:indexPath];
|
}
|
|
NSMutableArray *itemsInRow = [NSMutableArray array];
|
|
const NSInteger totalInSection = [self.collectionView numberOfItemsInSection:indexPath.section];
|
const CGFloat width = CGRectGetWidth(self.collectionView.bounds);
|
const CGRect rowFrame = CGRectMake(0, CGRectGetMinY(attributes.frame), width, CGRectGetHeight(attributes.frame));
|
|
// Go forward to the end or the row or section items
|
NSInteger index = indexPath.row;
|
while(index++ < totalInSection - 1) {
|
|
UICollectionViewLayoutAttributes *next = [super layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:index
|
inSection:indexPath.section]].copy;
|
|
if (!CGRectIntersectsRect(next.frame, rowFrame)) {
|
break;
|
}
|
[itemsInRow addObject:next];
|
}
|
|
// Current item
|
[itemsInRow addObject:attributes];
|
|
// Go backward to the start of the row or first item
|
index = indexPath.row;
|
while (index-- > 0) {
|
|
UICollectionViewLayoutAttributes *prev = [super layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:index
|
inSection:indexPath.section]].copy;
|
|
if (!CGRectIntersectsRect(prev.frame, rowFrame)) {
|
break;
|
}
|
[itemsInRow addObject:prev];
|
}
|
|
// Total items width include spacings
|
CGFloat totalWidth = self.minimumInteritemSpacing * (itemsInRow.count - 1);
|
for (UICollectionViewLayoutAttributes *item in itemsInRow) {
|
totalWidth += CGRectGetWidth(item.frame);
|
}
|
|
// Correct sorting in row
|
[itemsInRow sortUsingComparator:^NSComparisonResult(UICollectionViewLayoutAttributes *obj1, UICollectionViewLayoutAttributes *obj2) {
|
return obj1.indexPath.row > obj2.indexPath.row;
|
}];
|
|
CGRect rect = CGRectZero;
|
for (UICollectionViewLayoutAttributes *item in itemsInRow) {
|
|
CGRect frame = item.frame;
|
CGFloat x = frame.origin.x;
|
|
if (CGRectIsEmpty(rect)) {
|
x = self.sectionInset.left;
|
} else {
|
x = CGRectGetMaxX(rect) + self.minimumInteritemSpacing;
|
}
|
|
frame.origin.x = x;
|
item.frame = frame;
|
rect = frame;
|
|
[self.cache setObject:item forKey:item.indexPath];
|
}
|
|
[self.cache setObject:attributes forKey:indexPath];
|
return attributes;
|
}
|
@end
|