How to Recycle Uitableviewcell Objects Created from a Xib

How can I recycle UITableViewCell objects created from a XIB?

If you're using iOS 5 you can use

[self.tableView registerNib:[UINib nibWithNibName:@"nibname" 
bundle:nil]
forCellReuseIdentifier:@"cellIdentifier"];

Then whenever you call:

cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];

the tableview will either load the nib and give you a cell, or dequeue a cell for you!

The nib need only be a nib with a single tableviewcell defined inside of it!

Loading a Reusable UITableViewCell from a Nib

Just implement a method with the appropriate method signature:

- (NSString *) reuseIdentifier {
return @"myIdentifier";
}

How does loading view of a tableview cell from xib differ from dequereusablecellwithidentifier method?

When you display a table view, every cell is loaded when it's about to be displayed. dequeueReusableCellWithIdentifier allows you to take a cell that just got out of the screen and use it again for the one that will appear next. It's like recycling garbages.

This is how it works:

-(void)viewDidLoad{
...
[self.tableView registerNib:[UINib nibWithNibName:@"nibname"
bundle:nil]
forCellReuseIdentifier:@"CustomCellReuse"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Starting from iOS 5, the following will either dequeue an existing cell or instantiate a new one from xib
static NSString *CellIdentifier = @"CustomCellReuse";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
return cell;
}

If you don't reuse your cells, you will have serious performance issues on big table view.

But you can't "reuse" cells across different tableviews. you have to implement the previous method for both of them.

How Register Multiple TableViewCells from a xib file?

You can't create multiple custom cells on One xib. You need to create 5 different Xib's for 5 different cells. It's also easy for you to understand the code flow.

override func viewDidLoad() {
super.viewDidLoad()
intakeFormTableView.register(UINib(nibName: "IntakeFormViews1", bundle: nil), forCellReuseIdentifier: "IntakeFormTextFieldCell1")
intakeFormTableView.register(UINib(nibName: "IntakeFormViews2", bundle: nil), forCellReuseIdentifier: "IntakeFormButtonCell2")
intakeFormTableView.register(UINib(nibName: "IntakeFormViews3", bundle: nil), forCellReuseIdentifier: "IntakeFormButtonCell3")
intakeFormTableView.register(UINib(nibName: "IntakeFormViews4", bundle: nil), forCellReuseIdentifier: "IntakeFormButtonCell4")
intakeFormTableView.register(UINib(nibName: "IntakeFormViews5", bundle: nil), forCellReuseIdentifier: "IntakeFormButtonCell5")
// Do any additional setup after loading the view.
}

Using custom XIB in table view cell

You can use 2 ways:

Create UITableViewCell (better)

1) Change UIView to UITableViewCell

class CustomTableViewCell: UITableViewCell { 

...

class var identifier: String {
return String(describing: self)
}
}

2) Register your cell

override func viewDidLoad() {
super.viewDidLoad()

self.tableView.registerNib(UINib(nibName: CustomTableViewCell.identifier, bundle: nil), forCellReuseIdentifier: CustomTableViewCell.identifier)
...
}

3) Use cellForRow(at:)

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

let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as! CustomTableViewCell
cell.username.text = user.username

return cell
}

OR Add view as subview to cell (only in rare cases)

1) Add this to UserView

class UserView: UIView {

...

class func fromNib() -> UserView {
return UINib(nibName: String(describing: self), bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UserView
}

}

2) Use cellForRow(at:)

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

let cellIdentifier = "UserTableViewCell"

guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? UserTableViewCell else {
fatalError("The dequeued cell is not an instance of UserTableViewCell.")
}

let userView = UserView.fromNib()
let user = users[indexPath.row]
userView.username.text = user.username

//Use frame size, but for me better to add 4 constraints
userView.frame = CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)

cell.contentView.addSubview(UserView)

return cell
}

How to use UINib to instantiate and use custom UITableViewCells

  1. Create your xib file with a UITableViewCell as the top-level object. This is called Cell.xib
  2. Create a UINib object based on this file
  3. Register the UINib with the table view (typically in viewDidLoad of your table view controller subclass).

Steps 2 and 3 can be combined, so you would use the following line in viewDidLoad:

[self.tableView registerNib:[UINib nibWithNibName:@"Cell" bundle:nil] forCellReuseIdentifier:@"Cell"];

Then, in cellForRowAtIndexPath, if you want one of the cells from the nib, you dequeue it:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

This either creates a new instance from the nib, or dequeues an existing cell.

how to create custom tableViewCell from xib

Do not use UITableViewCell's initializer, but make the cell load from your nib:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
static NSString *CellIdentifier = @"EditCell";

EditCell *cell = (EditCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"YourNibNameHere" owner:self options:nil];
cell = (EditCell *)[nib objectAtIndex:0];
}
cell.editRow.text = @"some text to test";
return cell;
}

Of course, you need to specify the correct nib name.



Related Topics



Leave a reply



Submit