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
- Create your xib file with a UITableViewCell as the top-level object. This is called Cell.xib
- Create a UINib object based on this file
- 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
iOS 9 - "Attempt to Delete and Reload the Same Index Path"
iOS - Uiimagewritetosavedphotosalbum
Icloud + Coredata - How to Avoid Pre-Filled Data Duplication
Get List of All Installed Application in iOS 8
Decompilation Possibilities in iOS and How to Prevent Them
Xcode: "Scene Is Unreachable Due to Lack of Entry Points" But Can't Find It
Generics in Swift - "Generic Parameter 'T' Could Not Be Inferred
How to Convert .Dae to .Scn Files in Scenekit
Which Tasks Are More Suitable to Nsoperation Than Gcd
Ios: Present View Controller Programmatically
How to Make Sure API Requests Come from Our Mobile (Ios/Android) App
How to Expand Uicollectionview Contentsize When Paging Enable
Native Facebook Login Stopped Working After Sdk Update to 3.14
Over the Air (Ota) iOS IPA File Distribution for Public
Linker Errors When Trying to Install New Google Analytics 3.0 Beta
Set Uitableview Content Inset Permanently
Why Tesseract Ocr Library (Ios) Cannot Recognize Text at All