mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
added sample app that initializes ASCollectionView cells using view controllers, wip though
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
//
|
||||
// MosaicCollectionViewLayout.m
|
||||
// Sample
|
||||
//
|
||||
// Created by McCallum, Levi on 11/22/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MosaicCollectionViewLayout.h"
|
||||
|
||||
@implementation MosaicCollectionViewLayout {
|
||||
NSMutableArray *_columnHeights;
|
||||
NSMutableArray *_itemAttributes;
|
||||
NSMutableDictionary *_headerAttributes;
|
||||
NSMutableArray *_allAttributes;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
self.numberOfColumns = 3;
|
||||
self.columnSpacing = 10.0;
|
||||
self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
||||
self.interItemSpacing = UIEdgeInsetsMake(10.0, 0, 10.0, 0);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)prepareLayout
|
||||
{
|
||||
_itemAttributes = [NSMutableArray array];
|
||||
_columnHeights = [NSMutableArray array];
|
||||
_allAttributes = [NSMutableArray array];
|
||||
_headerAttributes = [NSMutableDictionary dictionary];
|
||||
|
||||
CGFloat top = 0;
|
||||
|
||||
NSInteger numberOfSections = [self.collectionView numberOfSections];
|
||||
for (NSUInteger section = 0; section < numberOfSections; section++) {
|
||||
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
|
||||
|
||||
top += _sectionInset.top;
|
||||
|
||||
if (_headerHeight > 0) {
|
||||
CGSize headerSize = [self _headerSizeForSection:section];
|
||||
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes
|
||||
layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
|
||||
withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
|
||||
attributes.frame = CGRectMake(_sectionInset.left, top, headerSize.width, headerSize.height);
|
||||
_headerAttributes[@(section)] = attributes;
|
||||
[_allAttributes addObject:attributes];
|
||||
top = CGRectGetMaxY(attributes.frame);
|
||||
}
|
||||
|
||||
[_columnHeights addObject:[NSMutableArray array]];
|
||||
for (NSUInteger idx = 0; idx < self.numberOfColumns; idx++) {
|
||||
[_columnHeights[section] addObject:@(top)];
|
||||
}
|
||||
|
||||
CGFloat columnWidth = [self _columnWidthForSection:section];
|
||||
[_itemAttributes addObject:[NSMutableArray array]];
|
||||
for (NSUInteger idx = 0; idx < numberOfItems; idx++) {
|
||||
NSUInteger columnIndex = [self _shortestColumnIndexInSection:section];
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:idx inSection:section];
|
||||
|
||||
CGSize itemSize = [self _itemSizeAtIndexPath:indexPath];
|
||||
CGFloat xOffset = _sectionInset.left + (columnWidth + _columnSpacing) * columnIndex;
|
||||
CGFloat yOffset = [_columnHeights[section][columnIndex] floatValue];
|
||||
|
||||
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes
|
||||
layoutAttributesForCellWithIndexPath:indexPath];
|
||||
attributes.frame = CGRectMake(xOffset, yOffset, itemSize.width, itemSize.height);
|
||||
|
||||
_columnHeights[section][columnIndex] = @(CGRectGetMaxY(attributes.frame) + _interItemSpacing.bottom);
|
||||
|
||||
[_itemAttributes[section] addObject:attributes];
|
||||
[_allAttributes addObject:attributes];
|
||||
}
|
||||
|
||||
NSUInteger columnIndex = [self _tallestColumnIndexInSection:section];
|
||||
top = [_columnHeights[section][columnIndex] floatValue] - _interItemSpacing.bottom + _sectionInset.bottom;
|
||||
|
||||
for (NSUInteger idx = 0; idx < [_columnHeights[section] count]; idx++) {
|
||||
_columnHeights[section][idx] = @(top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
|
||||
{
|
||||
NSMutableArray *includedAttributes = [NSMutableArray array];
|
||||
// Slow search for small batches
|
||||
for (UICollectionViewLayoutAttributes *attributes in _allAttributes) {
|
||||
if (CGRectIntersectsRect(attributes.frame, rect)) {
|
||||
[includedAttributes addObject:attributes];
|
||||
}
|
||||
}
|
||||
return includedAttributes;
|
||||
}
|
||||
|
||||
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section >= _itemAttributes.count) {
|
||||
return nil;
|
||||
} else if (indexPath.item >= [_itemAttributes[indexPath.section] count]) {
|
||||
return nil;
|
||||
}
|
||||
return _itemAttributes[indexPath.section][indexPath.item];
|
||||
}
|
||||
|
||||
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) {
|
||||
return _headerAttributes[@(indexPath.section)];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
|
||||
{
|
||||
if (!CGRectEqualToRect(self.collectionView.bounds, newBounds)) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (CGFloat)_widthForSection:(NSUInteger)section
|
||||
{
|
||||
return self.collectionView.bounds.size.width - _sectionInset.left - _sectionInset.right;
|
||||
}
|
||||
|
||||
- (CGFloat)_columnWidthForSection:(NSUInteger)section
|
||||
{
|
||||
return ([self _widthForSection:section] - ((_numberOfColumns - 1) * _columnSpacing)) / _numberOfColumns;
|
||||
}
|
||||
|
||||
- (CGSize)_itemSizeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGSize size = CGSizeMake([self _columnWidthForSection:indexPath.section], 0);
|
||||
CGSize originalSize = [[self _delegate] collectionView:self.collectionView layout:self originalItemSizeAtIndexPath:indexPath];
|
||||
if (originalSize.height > 0 && originalSize.width > 0) {
|
||||
size.height = originalSize.height / originalSize.width * size.width;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
- (CGSize)_headerSizeForSection:(NSUInteger)section
|
||||
{
|
||||
return CGSizeMake([self _widthForSection:section], _headerHeight);
|
||||
}
|
||||
|
||||
- (CGSize)collectionViewContentSize
|
||||
{
|
||||
CGFloat height = [[[_columnHeights lastObject] firstObject] floatValue];
|
||||
return CGSizeMake(self.collectionView.bounds.size.width, height);
|
||||
}
|
||||
|
||||
- (NSUInteger)_tallestColumnIndexInSection:(NSUInteger)section
|
||||
{
|
||||
__block NSUInteger index = 0;
|
||||
__block CGFloat tallestHeight = 0;
|
||||
[_columnHeights[section] enumerateObjectsUsingBlock:^(NSNumber *height, NSUInteger idx, BOOL *stop) {
|
||||
if (height.floatValue > tallestHeight) {
|
||||
index = idx;
|
||||
tallestHeight = height.floatValue;
|
||||
}
|
||||
}];
|
||||
return index;
|
||||
}
|
||||
|
||||
- (NSUInteger)_shortestColumnIndexInSection:(NSUInteger)section
|
||||
{
|
||||
__block NSUInteger index = 0;
|
||||
__block CGFloat shortestHeight = CGFLOAT_MAX;
|
||||
[_columnHeights[section] enumerateObjectsUsingBlock:^(NSNumber *height, NSUInteger idx, BOOL *stop) {
|
||||
if (height.floatValue < shortestHeight) {
|
||||
index = idx;
|
||||
shortestHeight = height.floatValue;
|
||||
}
|
||||
}];
|
||||
return index;
|
||||
}
|
||||
|
||||
- (id<MosaicCollectionViewLayoutDelegate>)_delegate
|
||||
{
|
||||
return (id<MosaicCollectionViewLayoutDelegate>)self.collectionView.delegate;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MosaicCollectionViewLayoutInspector
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MosaicCollectionViewLayout *layout = (MosaicCollectionViewLayout *)[collectionView collectionViewLayout];
|
||||
return ASSizeRangeMake(CGSizeZero, [layout _itemSizeAtIndexPath:indexPath]);
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MosaicCollectionViewLayout *layout = (MosaicCollectionViewLayout *)[collectionView collectionViewLayout];
|
||||
return ASSizeRangeMake(CGSizeZero, [layout _headerSizeForSection:indexPath.section]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary sections in the collection view for the given kind.
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind
|
||||
{
|
||||
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
|
||||
return [[collectionView asyncDataSource] numberOfSectionsInCollectionView:collectionView];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary views for the given kind in the specified section.
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
|
||||
{
|
||||
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user