Zayd Bhyat Zayd Bhyat - 15 days ago 11
Objective-C Question

how to create custom UICollectionViewCell

I have a

UICollectionView
and Im trying to set a
label
and an
image
in the
collectionViewCell
. Unfortunately I cant seem to get any labels to display or anything else for that matter.

Here is my code:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
}


Unfortunately no label is being displayed and neither is the text in the label.

Updated: I've added the rest of the code from this class file.

#import "ContainerListController.h"
#import "ContainerController.h"
#import "ContainerList.h"


@implementation ContainerListController


//Deallocate temp variables
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

//Initiate objects
- (id)init {
if (self = [super initWithTitle:LocStr(@"CONTAINER_LIST_TITLE") navBarHidden:NO]) {
m_paths = [ContainerList shared].paths;

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onContainerListDidChange)
name:kSDKLauncherContainerListDidChange object:nil];
}

return self;
}

//Load all the views.
- (void)loadView {
//Allocate a UI view
self.view = [[UIView alloc] init];

//Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

//Force Horizontal Scroll
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layout.minimumInteritemSpacing =[[UIScreen mainScreen] bounds].size.width;
layout.minimumLineSpacing=0.0;


//Create Collection
UICollectionView *coll =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];

//Allocations
m_coll = coll;
coll.dataSource =self;
coll.delegate =self;
coll.pagingEnabled = YES;
coll.collectionViewLayout = layout;

//Customize Cells
[coll registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[coll setBackgroundColor:[UIColor orangeColor]];

[layout invalidateLayout];

//Create the subview
[self.view addSubview:coll];




//set minimum spacing
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(@"Changed to landscape Spacing");
layout.minimumLineSpacing = 100.0f;
layout.minimumInteritemSpacing = 100.0f;
}
else{

layout.minimumLineSpacing = 40.0f;
layout.minimumInteritemSpacing = 40.0f;
}*/

//Old Layout
//UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//m_table = table;
//table.dataSource = self;
//table.delegate = self;
//[self.view addSubview:table];

}

- (void)onContainerListDidChange {
m_paths = [ContainerList shared].paths;
[m_table reloadData];
[m_coll reloadData];
}

//Debugging components function
/*-(void)printComps:(NSArray* ) components{
for (NSInteger i =0; i<16; i++) {
NSString * item;
item=components[i];
}
}*/

//old tableview cell
- (UITableViewCell *)
tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
cell.textLabel.text = (components == nil || components.count == 0) ?
@"" : components.lastObject;
return cell;
}

//Old tableView
- (void)
tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];

if (c != nil) {
[self.navigationController pushViewController:c animated:YES];
}
NSLog(@"Selected an item");
}

//old TableView count for epubs
- (NSInteger)
tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return m_paths.count;
}

- (void)viewDidLayoutSubviews {

//m_table.frame = self.view.bounds;
m_coll.frame = self.view.bounds;
}

//Collection View Cell Data Allocation
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
//UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
NSString *Title = components.lastObject;

NSLog(@"Title: %@",Title);
NSString *Titletest = components.lastObject;
NSInteger comp1 = components.count;
NSString *comps = @"components";
NSLog(@"There are: %ld %@", (long)comp1,comps);
NSLog(@"Title: %@",Titletest);
for (NSInteger i =0; i<15; i++) {
NSString * item;
item=components[i];
NSLog(@"Component:%ld %@",(long)i,components[i]);
}

return cell;
}

//Collection View Cell Data De-Allocation
- (void)
collectionView:(UICollectionView *)collectionView
numberofItemsInSection:(NSIndexPath *)indexPath{

[collectionView deselectItemAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];

if(c !=nil){
[self.navigationController pushViewController:c animated:YES];
}
}

//Collection
-(NSInteger)
collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{

return m_paths.count;
}


//Set Collection View Cell Size
-(CGSize)
collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{


//Set Landscape size of cells
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-360;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-60;
NSLog(@"Is Landscape");
return CGSizeMake(cellWidth, cellHeigt);
}
//Set Potrait size of cells
else{
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-60;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-160;
NSLog(@"Is Portrait");
return CGSizeMake(cellWidth, cellHeigt);
}*/

return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
}

//Collection View Cell Position
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {

if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
return UIEdgeInsetsMake(150.0,0.0,150.0,0.0); // top, left, bottom, right
}
else{
return UIEdgeInsetsMake(20.0,0.0,0.0,0.0); // top, left, bottom, right
}
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{

[m_coll performBatchUpdates:nil completion:nil];
}

-(void)viewWillTransitionToSize:withTransitionCoordinator{

[m_coll performBatchUpdates:nil completion:nil];
}

/*-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)
collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{

CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - ((cellCount-1) * (cellWidth + cellSpacing))) * 0.5;
inset = MAX(inset, 0.0);

if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){

NSLog(@"Changed to landscape Spacing");
return inset;

}
else{

return inset;
}

}*/
@end

Answer

Clear example to use custom collectionViewCell.

Create a separate class subclass ofUICollectionViewCell see below code:

.h file:

#import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *customLabel;
@end

.m file:

#import "CollectionViewCell.h"

@implementation CollectionViewCell

@end

Now drag and drop the collectionView inside viewController using storyboard then by selecting cell set custom class for it and connect its IBOutlet of label see below image.

Setting up custom class:

enter image description here

Connecting label's outlet: if adding label and other ui component from storyboard

enter image description here

Note: Drag uilabel inside cell before you connect its IBOutlet.


Now configure cell inside your viewController class. And configure collectionView correctly by connecting its delegate, dataSuorce and IBOutlet.

#import "ViewController.h"
#import "CollectionViewCell.h"

@interface ViewController (){
    // instance variable deceleration part 
    NSMutableArray *yourArray;
}
@end

@implementation ViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    _yourCollView.delegate = self;
    _yourCollView.dataSource = self;

    yourArray = [[NSMutableArray alloc] initWithObjects:@"1st cell",@"2nd cell",@"3rd cell",@"4th cell", nil];
    // Do any additional setup after loading the view, typically from a nib.
}

// collection view delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [yourArray count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"MyCustomCell" forIndexPath:indexPath];

    // configuring cell
    // cell.customLabel.text = [yourArray objectAtIndex:indexPath.row]; // comment this line if you do not want add label from storyboard 

    // if you need to add label and other ui component programmatically 
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
    label.tag = 200;
    label.text = [yourArray objectAtIndex:indexPath.row];

    // this adds the label inside cell
    [cell.contentView addSubview:label];

    return cell;
}

//Note: Above two "numberOfItemsInSection" & "cellForItemAtIndexPath" methods are required.

// this method overrides the changes you have made to inc or dec the size of cell using storyboard.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:   (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake(100, 100);
}

}  // class ends

Setup the cell identifier (by selecting a cell) MyCustomCell you have given inside cellForItemAtIndexPath method before use see below image:

enter image description here

Note: Change the text color of uilabel to white before because by default collectionView appears black.

Hope here you understand.

Comments