Reputation: 717
I need to add UICollectionView
into UICollectionViewCell
. It seems easy but I don't get it.
I don't get to know where I have to initialize UICollectionView
for each UICollectionViewCell
and where to program UICollectionViewDataSource
and UICollectionViewDelegate
of each UICollectionView
.
The result would be a collection of products (first collectionview
where each cell is a product) and a collection of images for each product like image gallery (second collection view where each cell is an image). It's the same as Zara app.
First collection view looks like this and have only vertical scroll.
When you select a product, cells change their size to full screen size and the collection view change vertical scrolling to horizontal scrolling. Now vertical scrolling is for the second collection view, the image gallery.
Second collection view looks like this
In storyboard I have UICollectionViewController
with UICollectionViewDataSource
, UICollectionViewDelegate
and UICollectionViewDelegateFlowLayout
implementations.
ProductsCollectionViewController.h
@interface ProductsCollectionViewController : UICollectionViewController <UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout> {
NSMutableArray *products;
}
ProductsCollectionViewController.m
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return products.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"ProductCell";
ProductCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
Product *product = [products objectAtIndex:indexPath.row];
[cell setProduct:product];
return cell;
}
Product is a main NSObject
that have some information and also an array
of images.
Product.h
@interface Product : NSObject
@property NSInteger categoryID;
@property NSInteger productID;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) NSArray *images;
I think that what I have to do is create new UICollectionView
programatically in each ProductCollectionViewCell
with the array
of images of the product but ProductCollectionViewCell
don't recognize UICollectionViewDataSource
and UICollectionViewDelegate
and their implementation.
Upvotes: 2
Views: 2997
Reputation: 27
Using StoryBoard is possible too.
Inspired in Ash Furrow's article
The main trick is in "willDisplayCell" method. Just make sure you are using the correct UICollectionViewCell class.
-(void)collectionView:(UICollectionView *)collectionView willDisplayCell:(PNCollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
if ([cell isKindOfClass:[PNCollectionViewCell class]]) {
[cell setCollectionViewDataSourceDelegate:self indexPath:indexPath];
NSInteger index = cell.collectionView.indexPath.row;
CGFloat horizontalOffset = [self.contentOffsetDictionary[[@(index) stringValue]] floatValue];
[cell.collectionView setContentOffset:CGPointMake(horizontalOffset, 0)];
}
}
For more details you can see my sample on: https://github.com/pnovales/UICollectionViewInUICollectionViewCell
Upvotes: 0
Reputation: 564
Lets start by having a mainCollectionView
. Then on each cell of this collection create and initialize a new UICollectionView
and right place to do that is in this following delegate of UICollectionView
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
e.g I initialize the MainCollectionViewCell
here and then MainCollectionViewCell
handles the logic to create a new UICollectionView
guard let collectionViewCell = cell as? MainCollectionViewCell else { return }
collectionViewCell.delegate = self
let dataProvider = ChildCollectionViewDataSource()
dataProvider.data = data[indexPath.row] as NSArray
let delegate = ChildCollectionViewDelegate()
collectionViewCell.initializeCollectionViewWithDataSource(dataProvider, delegate: delegate, forRow: indexPath.row)
collectionViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
Here is the initializer on MainCollectionViewCell
that creates a new UICollectionView
func initializeCollectionViewWithDataSource<D: protocol<UICollectionViewDataSource>,E: protocol<UICollectionViewDelegate>>(dataSource: D, delegate :E, forRow row: Int) {
self.collectionViewDataSource = dataSource
self.collectionViewDelegate = delegate
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .Horizontal
let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseChildCollectionViewCellIdentifier)
collectionView.backgroundColor = UIColor.whiteColor()
collectionView.dataSource = self.collectionViewDataSource
collectionView.delegate = self.collectionViewDelegate
collectionView.tag = row
self.addSubview(collectionView)
self.collectionView = collectionView
collectionView.reloadData()
}
Hope that helps !!
I did an example for this and put in on github. It demonstrates the use UICollectionView
inside a UICollectionViewCell
.
https://github.com/irfanlone/Collection-View-in-a-collection-view-cell
Upvotes: 2