Zayd Bhyat
Zayd Bhyat

Reputation: 101

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

Upvotes: 1

Views: 13209

Answers (3)

vaibhav
vaibhav

Reputation: 4096

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.

Upvotes: 4

Teja Nandamuri
Teja Nandamuri

Reputation: 11201

You are missing the:

  [cell.contentView addSubview:issue];

Upvotes: 0

Igor Kuznetsov
Igor Kuznetsov

Reputation: 108

  1. Create subclass of UICollectionViewCell. For instance TestCollectionViewCell.
  2. In Storyboard drag label in cell and set "Custom class" for this UICollectionViewCell with your created class. Set Reusable identifier, if your collection view in UIViewController don't forget to set DataSource and Delegate for that collectionView.
  3. Connect IBOutlet in your Cell subclass.
  4. Set at least 1 value inside numberOfItemsInSection method.
  5. Then use your subclass of cell in cellForItemAt and try set text for a label.

Upvotes: 3

Related Questions