Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Either implement the following delegate methods:</p> <pre><code>– collectionView:layout:sizeForItemAtIndexPath: – collectionView:layout:insetForSectionAtIndex: – collectionView:layout:minimumLineSpacingForSectionAtIndex: – collectionView:layout:minimumInteritemSpacingForSectionAtIndex: – collectionView:layout:referenceSizeForHeaderInSection: – collectionView:layout:referenceSizeForFooterInSection: </code></pre> <p>In your view controller that has your <code>:cellForItemAtIndexPath</code> method (just return the correct values). Or, instead of using the delegate methods, you may also set these values directly in your layout object, e.g. <code>[layout setItemSize:size];</code>.</p> <p>Using either of these methods will enable you to set your settings in Code rather than IB as they're removed when you set a Custom Layout. Remember to add <code>&lt;UICollectionViewDelegateFlowLayout&gt;</code> to your .h file, too!</p> <p>Create a new Subclass of <code>UICollectionViewFlowLayout</code>, call it whatever you want, and make sure the H file has:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; @interface YourSubclassNameHere : UICollectionViewFlowLayout @end </code></pre> <p>Inside the Implementation File make sure it has the following:</p> <pre><code>- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; UICollectionView * const cv = self.collectionView; CGPoint const contentOffset = cv.contentOffset; NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet]; for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) { [missingSections addIndex:layoutAttributes.indexPath.section]; } } for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) { [missingSections removeIndex:layoutAttributes.indexPath.section]; } } [missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx]; UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath]; [answer addObject:layoutAttributes]; }]; for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) { NSInteger section = layoutAttributes.indexPath.section; NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section]; NSIndexPath *firstCellIndexPath = [NSIndexPath indexPathForItem:0 inSection:section]; NSIndexPath *lastCellIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section]; NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0 inSection:section]; NSIndexPath *lastObjectIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section]; UICollectionViewLayoutAttributes *firstObjectAttrs; UICollectionViewLayoutAttributes *lastObjectAttrs; if (numberOfItemsInSection &gt; 0) { firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath]; lastObjectAttrs = [self layoutAttributesForItemAtIndexPath:lastObjectIndexPath]; } else { firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:firstObjectIndexPath]; lastObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:lastObjectIndexPath]; } CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame); CGPoint origin = layoutAttributes.frame.origin; origin.y = MIN( MAX( contentOffset.y + cv.contentInset.top, (CGRectGetMinY(firstObjectAttrs.frame) - headerHeight) ), (CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight) ); layoutAttributes.zIndex = 1024; layoutAttributes.frame = (CGRect){ .origin = origin, .size = layoutAttributes.frame.size }; } } return answer; } - (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound { return YES; } </code></pre> <p>Choose "Custom" in Interface Builder for the Flow Layout, choose your "YourSubclassNameHere" Class that you just created. And Run!</p> <p>(Note: the code above may not respect contentInset.bottom values, or especially large or small footer objects, or collections that have 0 objects but no footer.)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload