iOS UITableview Tutorial For Beginners : Part 3 – Custom Cells & Delegates

This is the third and final part in series ( iOS UITableView Tutorial For Beginners – Custom Cells & Delegates ). In this part we are going to create a completely custom cell with images, text and buttons positioned wherever we want them to be. For the buttons to work, we will also learn how to create delegates.

The complete Tutorial Series for UITableView For Beginners -

  1. iOS UITableview Tutorial For Beginners : Part 1
  2. iOS UITableview Tutorial For Beginners : Part 2 – Passing Data
  3. iOS UITableview Tutorial For Beginners : Part 3 – Custom Cells & Delegates

Prerequisites – iOS TableView Tutorial Custom Cells

  • Basic knowledge of iOS Development ( iOS – Tutorials )
  • Basic knowledge of default Tableview (Read part1 and part 2 of this series)

Final Project – iOS TableView Tutorial Custom Cells & Delegates

iOS UITableView Tutorial Custom Cells And Delegates

Theory

In the previous tutorials of this series, we made a twitter like app with default templates provided by Apple of Tableview. In this tutorial, we will make a custom cell so that we can use images, buttons or whatever other object we want to use.

Also, if you remember, we have used delegates before in the tutorials (eg setting self.tableview.delegate = self;). we were just setting the delegates until now, but in this tutorial we will make our own custom delegate as well before setting them. Now the questions arise -

  1. What is a delegate ? As the name suggests, a delegate is someone who represent someone else. In iOS, we set a class as delegate of tableview. This class tells the tableview that any action on you will be handled by me. In the last tutorial we used a delegate method didSelectRowAtIndexPath. So our class tells tableview that whenever one of your cells is tapped, I will handle what happens next using the method (didSelectRowAtIndexPath in this case).
  2. Why custom delegate ? For tableview, the default delegate methods are already made by Apple for us and we can use them directly, but if we are making a custom cell, we have to make our own delegate and its functions. We will make a delete button and make a delegate function for it (something like deleteTappedAtIndexPath ) .

Create A New Project

Open Xcode, click on File->New->Project and select Single View Application. Name the project Tableview Tutorial 3 and set class prefix as TVT. Create the project.

- Download the resources here. Unzip them and drag them to your project’s navigation panel. Make sure copy items into destination group’s folder is selected, leave the rest of the fields as they are and click finish.

- Next, Right click on Tableview Turorial 3 folder in the navigation panel and select new file. Select Objective-C class. Set the class name as TableCell and subclass of UITableViewCell. This class will handle our cell methods, properties and delegate.

Creating Views

- Go to mainstoryboard.storyboard in the navigation panel, select file inspector in the Utilities panel and deselect Autolayout. We will learn about autolayout in the later tutorials.

- Drag a UITableview from object library on our view controller and re-size it to cover the entire screen. Create an outlet in TVTViewController.m or .h and name it tableView.

-Keeping the tableview selected, click on attributes inspector and set the following properties

  • Content – Dynamic Properties
  • Prototype cells – 1

-Next click on the cell that shows when you set Prototype cell =1 and set the properties

  • In the identity inspector set class as TableCell (the name of the class we created before). This will link the cell’s view to our custom class.
  • In the attributes inspector, set Style as custom and Identifier as TableCellID
  • In the size inspector, check custom and set row height = 150.

-Let’s make our cell more custom by giving it a different syle. On the newly created cell, make the following changes -

  • Drag an imageView to fill out the entire cell and set it’s image as cell_bg.jpg. This will act as cell background
  • Next drag a button and place it somewhere on the lower right. Set it’s image as delete.png. Also create an IBAction as deleteTapped in the class TableCell.m
  • Drag another imageView and place it somewhere on the middle left and set it’s outlet as cellImage in TableCell.h. This will be used to show a thumbnail for each cell.
  • Drag a UILabel whereever there is some place left on the cell and set it’s outlet as title.

Your cell should look something like this -

ios Uitableview Tutorial - custom cell

Let’s Code -

We will first setup our cell to show the title and corresponding thumbnail image and later on we will make a custom delegate for our cell for delete button to work.

Replace the TVTViewController.h with the following -

#import <UIKit/UIKit.h>
#import "TableCell.h"

@interface TVTViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (strong, nonatomic) NSMutableArray *tweetsArray;

@end

Next, replace the viewDidLoad method in TVTViewController.m with -

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
  //1
  self.tableView.delegate = self;
  self.tableView.dataSource = self;

  //2
  NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"1.png",@"image",
                         @"Always put your fears behind you and your dreams in front of you.",@"tweet", nil];
  NSDictionary *dict2 = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"2.png",@"image",
                         @"A relationship with no trust is like a cell phone with no service, all you can do is play games.",@"tweet", nil];
  NSDictionary *dict3 = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"3.png",@"image",
                         @"People should stop talking about their problem and start thinking about the solution.",@"tweet", nil];

  self.tweetsArray = [NSMutableArray arrayWithObjects:dict1,dict2,dict3, nil];

}

1)First we set the datasource and delegate of tableview as our current class, i.e. self.

2)We create 3 dictionaries, one for each cell, each consisting of an image and a tweet. The image name is the same as in our resources folder which we downloaded and dragged to our project earlier. We then add these 3 dictionaries in our tweetsArray. Although you should not store your data this way but for the sake of this tutorial, this method should just work fine.

Next add the following tableview methods below viewDidLoad in TVTViewController.m -

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  return self.tweetsArray.count;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  return 150;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *cellIdentifier = @"TableCellID";
  //3
  TableCell *tablecell = (TableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

  //3.1 you do not need this if you have set TableCellID as identifier in the storyboard (else you can remove the comments on this code). Do not use this code if you are following this tutorial
  //if (cell == nil)
  //    {
  //        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
  //   }

  //3.2
  NSDictionary * dict = [self.tweetsArray objectAtIndex:indexPath.row];

  tablecell.title.text = [dict objectForKey:@"tweet"];

  UIImage *imageIcon = [UIImage imageNamed:[dict objectForKey:@"image"]];
  [tablecell.cellImage setImage:imageIcon];

  //4
  return tablecell;

}

3) Here we are using TableCell *(our custom class ) instead of UITableViewCell * so that we can access our custom properties (cellImage and title) directly from here.

3.2)We fetch the dictionary corresponding to the cell using indexPath and set our cell’s title and image.

Run the App (Command+R) and you should be able to see your first custom cell. Only the delete button will not work which we will handle now!

Custom Delegates – iOS TableView Tutorial

We are now going to create our very first custom delegate. You have been setting tableview.delegate  = self; many times before without knowing whats really happening. Well the time has come for you to know the ultimate secret. Well! not so ultimate or secret. Anyways lets start

Firstly, we will create a delegate – Go to TableCell.h and add the following lines of code right before @interface:TableCell and right after #import statements if any -

//5
@protocol TableCellDelegate
@optional
- (void)deleteButtonTappedOnCell:(id)sender;
@end

5) This is how we make a delegate @protocol delegate-name <NSObject>, followed by delegate methods – (such as cellForRowAtIndexPath as in the case of tableview.

Next, add the following property inside @interface and @end

@property (nonatomic, strong) id  delegate;

Here the name delegate can be changed to anything. So if we replace delegate as someDelegate, the only difference would be that while setting the delegate we will use tablecell.someDelegate = self;

Your tableCell.h should look something like this -

#import <UIKit/UIKit.h>

//5
@protocol TableCellDelegate
@optional
- (void)deleteButtonTappedOnCell:(id)sender;
@end

@interface TableCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *title;
@property (weak, nonatomic) IBOutlet UIImageView *cellImage;
@property (nonatomic, strong) id  delegate;

@end

Next, go to TableCell.m and add the following line inside our IBAction for delete button -

[self.delegate deleteButtonTappedOnCell:self];

What this does is that whenever delete is tapped on cell, this code is called and the delegates are notified that there is some message for them.

This is all that happens in the back. Now we will set our class TVTViewController as delegate or listener to tablecell’s delegate.

Go to TVTViewController.h and replace

@interface TVTViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

with

@interface TVTViewController : UIViewController <UITableViewDataSource, UITableViewDelegate,TableCellDelegate>

Sounds familiar, doesn’t it? That’s what you have been doing before with UITableViewDelegate .

Next go to TVTViewCOntroller.m and add the following line inside cellForRowAtIndexPath right below //4.

tablecell.delegate = self;

this will set the current class as delegate of each cell.

Finally add the delegate method -

- (void)deleteButtonTappedOnCell:(id)sender {
  NSIndexPath *indepath = [self.tableView indexPathForCell:sender];

  [self.tweetsArray removeObjectAtIndex:indepath.row];

 [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indepath]
                       withRowAnimation:UITableViewRowAnimationAutomatic];

}

This method will be called whenever delete is tapped on a cell. First we get the indexPath for the cell tapped. We then remove the object from the tweets array. We could have called [tableView reloadData]; but we use the above method deleteRowsAtIndexPath for a sweet animation when deleting.

That’s it. Run the program and congratulations on reaching this far. The series ends here.

Source Code- iOS TableView Tutorial Custom Cells & Delegates

You can download the complete source code here.

What’s Next

The complete Tutorial Series for UITableView For Beginners -

  1. iOS UITableview Tutorial For Beginners : Part 1
  2. iOS UITableview Tutorial For Beginners : Part 2 – Passing Data
  3. iOS UITableview Tutorial For Beginners : Part 3 – Custom Cells & Delegates

If you have any doubts/ feedback, please use the comments section. If this tutorial was helpful to you, please leave some feedback!

About Bharat

is an iOS developer and aims at helping people learn and master iOS development. He graduated from IIT Kanpur and loves gadgets and new technology. He is also the admin of this site.

2 comments

  1. Excellent article. The way you explain is very clear.

    Somewhere near the beginning you said: “…We then add these 3 dictionaries in our tweetsArray. Although you should not store your data this way but for the sake of this tutorial…” Can you explain a little bit why we should not store the data this way? What would be the preferred way?

    Thanks.

    • What I meant was you should store data in a different model class or in core data (database of iPhone) or get through some serve so that we follow MVC framework.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Scroll To Top