Reputation: 13546
I am new to Collectionview
, but not to iOS. I am using custom Flowlayout for my collectionview. I need to return contentsize based on current number of items returned by CollectionView's data source. Is there anyway to know how many items are there currently in flowlayout's collectionview?
@interface LatestNewsFlowLayout : UICollectionViewFlowLayout
-(id)initWithSize:(CGSize) size;
@end
@implementation LatestNewsFlowLayout
-(id)initWithSize:(CGSize) size {
self = [super init];
if (self) {
self.itemSize = size;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(0, 10.0, 0, 0);
self.minimumLineSpacing = 5;
}
return self;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)oldBounds {
return YES;
}
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
for(int i = 1; i < [answer count]; ++i) {
UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
NSInteger maximumSpacing = 5;
NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = origin + maximumSpacing;
currentLayoutAttributes.frame = frame;
}
}
return answer;
}
-(CGSize) collectionViewContentSize
{
CGSize size;
int numOfItems = ???
size.width = 100 * numOfItems;
size.height = 100;
return size;
}
Upvotes: 10
Views: 23758
Reputation: 641
I like Vadim's answer because it is swifty and clean, but we're creating an array from a range and looping it twice (map and reduce). I'd suggest a similar solution using directly a range with only one loop (reduce):
let totalItems = (0..<collectionView.numberOfSections)
.reduce(0) { res, cur in
res + collectionView.numberOfItems(inSection: cur)
}
In my case I ended up creating an extension for UICollectionView
:
extension UICollectionView {
var totalItems: Int {
(0..<numberOfSections).reduce(0) { res, cur in
res + numberOfItems(inSection: cur)
}
}
}
And then just:
collectionView.totalItems
Upvotes: 3
Reputation: 3877
Swifty solution is next:
let itemsCount = Array(0..<collectionView.numberOfSections)
.map { collectionView.numberOfItems(inSection: $0) }
.reduce(0, +)
Now itemsCount
contains total number of collection view items across all sections.
Upvotes: 4
Reputation: 2805
+ (NSInteger)countInCollectionView:(UICollectionView *)collectionView {
NSInteger itemCount = 0;
for( int section = 0; section < [collectionView numberOfSections]; ++section ){
itemCount += [collectionView numberOfItemsInSection:section];
}
return itemCount;
}
Upvotes: 1
Reputation: 6197
In Swift, you can write the following (provided that you have a data source with sections and items):
let totalItemCount = sections.reduce(0) { result, section -> Int in
return result + section.items.count
}
Just replace section
with your data source, and items
with the item collection name.
Upvotes: 1
Reputation: 2632
If you make a property/outlet called collectionView, try this:
for (int i = 0; i<[collectionView numberOfSections];i++) {//Iterate through all the sections in collectionView
for (int j = 0; j<[collectionView numberOfItemsInSection:i]; j++) {//Iterate through all the rows in each section
numOfItems++;
}
}
Upvotes: 1
Reputation: 4905
The UICollectionViewFlowLayout is a subclass of UICollectionViewLayout. It should therefore have access to the UICollectionView which should know how many items there are.
[self.collectionView numberOfItemsInSection:0];
You may need to iterate over the section to get the total number of items if you have more that one section.
You can get the number of sections similarly:
[self.collectionView numberOfSections];
Hope this helps! :)
Upvotes: 26