How to add a background image to a UICollectionView that will scroll and scale cells

I am creating a mosaic view using a UICollectionView .

I have subclassed UICollectionViewFlowLayout for a fixed grid layout that can be scrolled both horizontally and vertically . I also added a UIPinchGestureRecognizer , so the collection can be scaled / scaled.

Each cell in the collection contains UIImage with some transparency. I want to add a background image that will scroll and scale using cells.

I tried to implement several different solutions.

  • setting the background color of a UICollectionView using colorWithPatternImage . (do not scroll / resize content)
  • setting the display of the background image for each cell on the corresponding cropped part of the background image. (uses too much memory)

I study complementary and decorative ideas, but try my best to hug him. I think I need to use additional views, since the image used in the background will change depending on the datasource .

I don’t understand how I can register only one additional view to cover the width and height of the entire collectionview . They seem to be attached to indexPath each cell.

+6
source share
1 answer

I don’t know if you found the answer ...!

You are on the right track, wanting to use additional views. The index path of the secondary view is not bound to a cell; it has its own index path.

Then in your subclass of UICollectionViewFlowLayout you need to subclass several methods. docs are pretty good!

In the layoutAttributesForElementsInRect: method layoutAttributesForElementsInRect: you need to call super, and then add another set of layout attributes for your additional view.

Then in layoutAttributesForSupplementaryViewOfKind:atIndexPath: you set the size of the returned attributes to the size of the contents of the collection view so that the image fills all the content, not just the frame. You probably also want to set the z-order to make sure that it is behind the cells. See Docs for UICollectionViewLayoutAttributes

 @implementation CustomFlowLayout -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; // Use your own index path and kind here UICollectionViewLayoutAttributes *backgroundLayoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:@"background" atIndexPath:[NSIndexPath indexPathWithItem:0 inSection:0]]; [attributes addObject:backgroundLayoutAttributes]; return [attributes copy]; } -(UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath if ([kind isEqualToString:@"background"]) { UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kind withIndexPath:indexPath]; attrs.size = [self collectionViewContentSize]; attrs.zIndex = -10; return attrs; } else { return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath]; } } @end 

In your collection view data source, you need this method: collectionView:viewForSupplementaryElementOfKind:atIndexPath:

 -(void)viewDidLoad { [super viewDidLoad]; // Setup your collection view UICollectionView *collectionView = [UICollectionView initWithFrame:self.view.bounds collectionViewLayout:[CustomFlowLayout new]]; [collectionView registerClass:[BackgroundReusableView class] forSupplementaryViewOfKind:@"background" withReuseIdentifier:@"backgroundView"]; } - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { if ([kind isEqualToString:@"background"]) { BackgroundReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"backgroundView" forIndexPath:indexPath]; // Set extra info return view; } else { // Shouldn't be called return nil; } } 

Hope all that should get you on the right track :)

+4
source

All Articles