So I have a collection view controller that has 3 cells because each cell will have a different layout. My image shows this:
They all have different cell identifiers so in my cellForItemAtIndexPath function I can create the specific cell like:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell;
if(indexPath.row == 0)
{
static NSString *identifier = #"Cell1";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
[cell setNeedsLayout];
}
else if(indexPath.row == 1)
{
static NSString *identifier = #"Cell2";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
[cell setNeedsLayout];
}
else
{
static NSString *identifier = #"Cell3";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
[cell setNeedsLayout];
}
return cell;
}
But when I simulate it, all the cells come out the same size:
Is there a way to force the cell to be the size I have defined or is there a more appropriate way of doing this?
Try this : Custom layout for different cell sizes in UICollectionView
or use this method :
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
Related
I would like to use two CollectionViewCell in the same CollectionViewController.
Can you help me please ?
thanks
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
cell.textLabel.text = [NSString stringWithFormat:#"%li", (long)indexPath.row + 1];
return cell;
}
Give each cell type a unique reuse identifier and, if necessary, a custom subclass of UICollectionViewCell. In your cellForItemAtPath function, use the identifier to get the one that's appropriate for the path, e.g.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.item % 2 == 0) {
EvenCollectionViewCell *cell = (EvenCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier: "evenCell" forIndexPath :indexPath];
// Configure the cell
...
return cell;
} else {
OddCollectionViewCell *cell = (OddCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier: "oddCell" forIndexPath: indexPath];
// Configure the cell
...
return cell;
}
}
I have my data source methods
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 10;
}
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
LPDiaryCollectionViewCell *cell = (LPDiaryCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.testLabel.text = #"test";
return cell;
}
The cell is registered
[self.collectionView registerClass:[LPDiaryCollectionViewCell class] forCellWithReuseIdentifier:#"cell"];
Datasource, delegate and outlet are connected
But when I run, datasource methods don't get called and view is plain white with no UICollectionView showing.
EDIT: added the uicollectionview programattically instead. It displays but still no cell.
You have to set cell identifier for collection view cell in storybord(Ex. I have declared identifier = "ReuseCell") and used same storyboard identifer in cellForItemAtIndexPath method.
static NSString *identifier = #"ReuseCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
static NSString *identifier = #"Yourcellname";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
I have the following code:
- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
How do I add a counter to dispaly in my cell that shows the number of the cell in the order it was created? Like cell 1 would say 1, 2 is 2, and so on.
Create a subclass of UICollectionViewCell. Add the counter (maybe just a label?) in the init method of the cell. Register you class for a cell identifier of your wish
[self.collectionView registerClass:[MyCollectionViewCell class]
forCellWithReuseIdentifier:#"myCellIdentifier"];
and dequeue the cell with the identifier. Then set the label value.
- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"myCellIdentifier" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.counterLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
There is any code like this one that work with UICollectionViewCell when the method reuse ?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellId = [NSString stringWithFormat:#"CellId%d%d",indexPath.row,indexPath.section];
if (!cell)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellId] autorelease];
}
return cell;
}
The whole point is to reuse cells, that's why the reuse identifier should be the same for all cells, at least all cells of one class (that's why it makes sense to declare CellId as a static variable - this method will be called a lot). dequeueReusableCellWithReuseIdentifier: method returns cell ready to be reused, if any. If there is no such cell you should create it and later, when it is no longer visible UICollectoinView will add it into "reusable cells pool" and return for dequeueReusableCellWithReuseIdentifier:.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellId = #"YourCellIdentifier";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellId];
if (!cell) {
cell = [[CustomCell alloc] initWithFrame:yourFrame];
}
return cell;
}
Yes, there is a similar method for collectionview as shown below:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"collectionCell";
collectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
Yes, there is:
UICollectionReusableView *collView = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
You can find the info in the docs:
https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionView_class/Reference/Reference.html#//apple_ref/occ/instm/UICollectionView/dequeueReusableCellWithReuseIdentifier:forIndexPath:
I am new to UICollectionView.
I have followed this tutorial to learn how to use a UICollectionView, but the problem is that in the .xib (not using storyboard) I am not able to add UICollectionViewCell as a subview of UICollectionView.
In the tutorial the cell is automatically created under UICollectionView in the .xib.
Any help would be appreciated.
That tutorial is for working in stroy board in xib you ve to create custom cell first create view controller add UicollectionView to view Controller
then create custom class for collection cell
then craete empty xib resource and add collection view cell
and set class name and identifier for that control
then create delegates method to add custom cell to ur collectionViewController
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"customCell";
customCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
You can start your controller and create a custom collection view cell for setting your view element and then you can use it into your collection view controller into xib, here is a good tutorials to do this http://adoptioncurve.net/archives/2012/09/a-simple-uicollectionview-tutorial/
Use this code for creation of collectionview and adding the subview.
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return [imageArray count];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSMutableArray *sectionArray = [imageArray objectAtIndex:section];
return [sectionArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// Setup cell identifier
static NSString *cellIdentifier = #"cvCell";
/* Uncomment this block to use nib-based cells */
// UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
// UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
// [titleLabel setText:cellData];
/* end of nib-based cell block */
/* Uncomment this block to use subclass-based cells */
CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
NSMutableArray *data = [imageArray objectAtIndex:indexPath.section];
NSString *cellData = [data objectAtIndex:indexPath.row];
[cell.titleLabel setText:cellData];
cell.imageView.image = [UIImage imageNamed:[imageArray[indexPath.section] objectAtIndex:indexPath.row]];
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
header *sectionHeader;
if (kind == UICollectionElementKindSectionHeader)
{
sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"Hello" forIndexPath:indexPath];
}
UICollectionReusableView *test=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"Hello" forIndexPath:indexPath];
return test;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
if (section == 3) {
return CGSizeMake(0, 100);
}
return CGSizeZero;
}
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(80, 80);
}