How to Load Custom Uitableviewcells from Xib Files

How do you load custom UITableViewCells from Xib files?

Here are two methods which the original author states was recommended by an IB engineer.

See the actual post for more details. I prefer method #2 as it seems simpler.

Method #1:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Create a temporary UIViewController to instantiate the custom cell.
UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
// Grab a pointer to the custom cell.
cell = (BDCustomCell *)temporaryController.view;
[[cell retain] autorelease];
// Release the temporary UIViewController.
[temporaryController release];
}

return cell;
}

Method #2:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}

return cell;
}

Update (2014):
Method #2 is still valid but there is no documentation for it anymore. It used to be in the official docs but is now removed in favor of storyboards.

I posted a working example on Github:

https://github.com/bentford/NibTableCellExample

edit for Swift 4.2

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
self.tblContacts.register(UINib(nibName: CellNames.ContactsCell, bundle: nil), forCellReuseIdentifier: MyIdentifier)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: MyIdentifier, for: indexPath) as! ContactsCell

return cell
}

Load UITableViewCell to UITableView in xib file

First for Your MainTableView Just Register Normal Cell from Xib
Just do it normal and DepartureDetailTableViewCell will have all Datasource and delegate for Inside cell Like that :

don't forget to write correct cell identifiers and so on

In ViewController :

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {


override func viewDidLoad() {
super.viewDidLoad()

self.tableView.register(UINib.init(nibName: "DepartureDetailTableViewCell", bundle: nil), forCellReuseIdentifier: "DepartureDetailsTableViewCell")
self.tableView.delegate = self
self.tableView.dataSource = self

}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DepartureDetailTableViewCell", for: indexPath) as! DepartureDetailTableViewCell
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4 // cell data source
}
}

In DepartureDetailTableViewCell:

class DepartureDetailTableViewCell: UITableViewCell {

@IBOutlet weak var tableView:UITableView!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code

self.tableView.register(UINib.init(nibName: "DepartureInsideTableViewCell", bundle: nil), forCellReuseIdentifier: "DepartureInsideTableViewCell")
self.tableView.delegate = self
self.tableView.dataSource = self
}


}

extension DepartureDetailTableViewCell: UITableViewDelegate,UITableViewDataSource{

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DepartureInsideTableViewCell", for: indexPath) as! DepartureInsideTableViewCell
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4 // cell data source
}
}

How to load Custom cell (Xib) in UITableview using Swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

//MARK:- Sample Data Array to load in TableView
let sampleArrray: \[String\] = \["val1", "val2", "val3", "val4", "val5"]

//MARK:- Cell reuse identifier
let cellReuseIdentifier = "cell"


//MARK:- UITableView outlet
@IBOutlet var tableView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

// Registering the custom cell

self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)

// Setting delegate and Datasourse as same viewcontroller (this code is not neccessory if we are setting it from storyboard)

tableView.delegate = self
tableView.dataSource = self
}
//UITableview required methods

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sampleArrray.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier) as UITableViewCell!

cell.textLabel?.text = sampleArrray\[indexPath.row\]

return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("clicked at: \(indexPath.row)")
//Here u can get the selected cell and add action related to this cell seelction
}

Added Screenshot for setting Datasource and delegate from storyboard
Sample Image

Linking multiple custom UITableViewCell's to single xib

Add view loaded by xib to UITableViewCell classes in which you want to use it.

  1. Create your xib as per your require design, in your example PickerTableViewCell.xib

  2. Create UITableViewCell sub-classes in which you want to use that view. I am using FirstTableViewCell & SecondTableViewCell for this.

in constructor of table cell load the xib and add it to table cell.

let nib = Bundle.main.loadNibNamed("PickerTableViewCell", owner: nil, options: nil)
if let view = nib?.first as? UIView{
self.addSubview(view)
}

if xib have any @IBOutlet then get them by viewWithTag function and assign to class variables

if let label = self.viewWithTag(1) as? UILabel{
self.label = label
}

override reuseIdentifier var of each tableviewCell subclass with different name

override var reuseIdentifier: String?{
return "FirstTableViewCell"
}

Now You can use these classes where you want, for using this follow below steps:

register this tableviewCell subclass with xib with tableview:

tableView.register(FirstTableViewCell.self, forCellReuseIdentifier:"PickerTableViewCell")

now in cellForRowAt indexPath method use it.

var cell = tableView.dequeueReusableCell(withIdentifier: "FirstTableViewCell", for: indexPath) as? FirstTableViewCell
if cell == nil {
cell = FirstTableViewCell()
}
cell?.label?.text = "FirstTableViewCell"

Loading custom XIB for UITableViewCell

Make sure you've set the ItemCell identifier in your XIB and also that your table datasource is set. Then move your registerNib to viewDidLoad

-(void)viewDidLoad {
//...
self.tableview.dataSource = self;
[self.tableView registerNib:[UINib nibWithNibName:@"CustomTableViewCell" bundle:nil] forCellReuseIdentifier:@"ItemCell"];

}

and the in cellForRowAtIndexPath:

CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell" forIndexPath:indexPath];

and remove the if (!cell) block, it won't be used anyway.

How to add a custom UITableViewCell to a xib file objective-c

You can do like this in Tableview cellforrowAtIndexPath methods,

static NSString *CellIdentifier = @"CellData";

NSArray *arrData = [[NSBundle mainBundle]loadNibNamed:@"cellTaskDetail" owner:nil options:nil];

cellTaskDetail *cell = [[cellTaskDetail alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell = [arrData objectAtIndex:0];

return cell;

Its work fine...do it



Related Topics



Leave a reply



Submit