Pregunta

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;
}
¿Fue útil?

Solución

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! :)

Otros consejos

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.

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++;
    }
}

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.

+ (NSInteger)countInCollectionView:(UICollectionView *)collectionView {
   NSInteger itemCount = 0;
   for( int section = 0; section < [collectionView numberOfSections]; ++section ){
      itemCount += [collectionView numberOfItemsInSection:section];
   }
   return itemCount;
}

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top