How to use multiple reusable TableViewCells - ios

I like to add multiple reusable UITableViewCells to a TableView. I am using this code to do this, but it won't work, it only shows the first cell.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
static NSString *costumeCell1 = #"Cell1";
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1];
if (!cell1) {
cell1 = [[AppDetailCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell1];
}
return cell1;
}
if (indexPath.row == 1) {
static NSString *costumeCell2 = #"Cell2";
AppDetailCell2 *cell2 = [tableView dequeueReusableCellWithIdentifier:costumeCell2];
if (!cell2) {
cell2 = [[AppDetailCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell2];
}
return cell2;
} else {
return nil;
}
}

If you set the reuse identifiers properly, you should change this code part
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1];
if (!cell1) {
cell1 = [[AppDetailCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell1];
}
with this
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1 forIndexPath:indexPath];
There is no need if(!cell1), because dequeueReusableCellWithIdentifier: forIndexPath: method never returns nil, as I said before that properly reuse identifier set is important.

Related

How to append custom tableviewcells to tableview one by one

I have two tableview controllers lets say PopoverElementsListTable ,ElementsViewTable. one tableview will be in popover state when I click on one of the PopoverElementsListTable cell a custom cell has to added to the ElementsViewTable.I'm able to append only one cell when I try to add another cell to ElementsViewTable its getting replaced with previous cell.
#pragma mark - TableView delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section{
if (tableView == PopoverElementsListTable) {
return [myArray count];
}
else if (tableView == ElementsViewTable) {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
if (tableView == PopoverElementsListTable) {
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}else {
NSLog(#"_selectedIndex %lu",(unsigned long)_selectedIndex);
if(_selectedIndex == 1){
AutoFillAddressFormElementcell * cell = [tableView dequeueReusableCellWithIdentifier:#"autoAddressCell"];
if (!cell) {
cell = [[AutoFillAddressFormElementcell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"autoAddressCell"];
}
return cell;
}else if(_selectedIndex == 2){
NSLog(#"Test # 123");
AddressSetterFormElementCell * cell = [tableView dequeueReusableCellWithIdentifier:#"setAddressCell"];
if (!cell) {
cell = [[AddressSetterFormElementCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"setAddressCell"];
}
return cell;
}else{
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = #"List";
return cell;
}
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
if(tableView == PopoverElementsListTable){
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %#",
(long)indexPath.section,(long)indexPath.row,cell.textLabel.text);
[_transarentView setHidden:true];
_selectedIndex = indexPath.row + 1;
NSLog(#"number %lu",(unsigned long)_selectedIndex);
[_displayFromElementTableView reloadData];
}
if(tableView == ElementsViewTable){
}
}
I know I'm able to append only one item because of return 1 in numberOfRowsInSection delegate. I tried replacing with another number but what I achieved is all the cells are identical.How can I get the dynamic count here? How to append customcells one by one which are unidentical.
You need to do it by identifying indexpath .
if (indexPath.row == 0) {
Customcell1 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}else if (indexPath.row == 1){
Customcell2 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}
return cell;
and so on....
You can check the table view too if you want.

Optimize CellForRow Method for multiple cells

Can anyone help me with how to optimize following code if we do have same contents inside both the cells such like 2 labels and 1 imageview than.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == booksTbl) { // Your conditions here to choose between Books and Movies
BookCell *cell = [tableView dequeueReusableCellWithIdentifier:#"bookCell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"bookCell"];
}
return cell;
} else {
MovieCell *cell = [tableView dequeueReusableCellWithIdentifier:#"movieCell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"movieCell"];
}
return cell;
}
I have tried by taking UITablewViewCell As common and according to condition, i was casting it with the appropriate cell. But it doesn't work for me.
Try this one:
BookCell *cell = (BookCell*)[tableView dequeueReusableCellWithIdentifier:#"bookCell"];
if(cell == nil){
// NSLog(#"---Cell Allocated Memory---");
cell = (BookCell *)[[[NSBundle mainBundle] loadNibNamed:#"BookCell" owner:nil options:nil] lastObject];
[cell setRestorationIdentifier:#"bookCell"];
}

Reusable custom cell

I have a tableView with a custom cell. I have the posibility to save to favorites some of the elements , and when this is happening i want to add a star image in cell. I was trying doing this , but after the star appears, i have a problem . I think it's because of reusable cell but i dont know how to solve it . My problem is : stars appear again on the other cells even if the word is not added on favorites.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[dictionaryTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.word.text = self.tableData[indexPath.row];
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
}
return cell;
}
Replace following code in place of cellForRowAtIndexPath. you will get your desire output.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[dictionaryTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.favImg.hidden = YES;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.word.text = self.tableData[indexPath.row];
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.hidden = NO;
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
}
return cell;
}
Hope this help you.
You have to remove the image if the object is not TRUE
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
} else {
cell.favImg.image=nil;
}
Yes, you are right it's because of reusing your cells via dequeueReusableCell with identifier as-
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
according to your requirements you set a star image on a cell to indicate some favorite elements on the respective cell, like this
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
When any cell with star image is reused than it should be removed if the next cell does not some favorite elements but if it does have some favorite elements than it should be used as-
To resolve this issue just add the else case with the above if statement as
if (isTheObjectThere == TRUE)
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
else
cell.favImg.image=nil;

Cell at indexpath 0 not displaying correctly

I have a UITableView with sections inside of them. All works great, but I can't seem to figure out how to customize the very fist index path. For example, I know this is very easily achievable through a normal tableview like so:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
if (indexPath.row == 0)
{
cell.detailTextLabel.text = #"My Custom text";
NSLog(#"%#",pm1.customText1);
}
}
}
I have tried the above implementation and it does not seem to work for me. Is there a different approach for section headers to achieve the same result with a normal tableview? Do I need to inject a "fake" section in my dictionary?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0) {
cell.detailTextLabel.text = #"My Custom text";
NSLog(#"%#",pm1.customText1);
}
return cell;
}
Try this
The way you have it now the first cell is customize only when cell is nil.
You should move it out of the if statement.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//check for first cell
if (indexPath.row == 0) {
cell.detailTextLabel.text = #"My first Cell";
NSLog(#"%#",pm1.customText1);
}else{
cell.detailTextLabel.text = #"Other cells";
NSLog(#"other cells");
}
return cell;
}

*** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:]

I am using tableview apple's lazy loading code in my project,but having exception in project. And error is - *** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:],here is my code please help.But it is working in other project.I have no delegate method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
NSUInteger nodeCount = [self.entries count];
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.text = #"Loading…";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nodeCount > 0)
{
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.name;
if (!appRecord.appIcon)
{
if (self.mytable_view.dragging == NO && self.mytable_view.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
Because cellForRowAtIndexPath is returning a nil value and then configureCellForDisplay is expecting a UITableViewCell. The storyboard or XIB does not have a cell defined with the cell identifier you specified. Better check the spelling of identifier.
Please check for Delegate.
Have you added both delegate or not?
UITableViewDelegate, UITableViewDataSource
import UIKit
class UserFriendVC: UIViewController, UITableViewDelegate, UITableViewDataSource
{
override func viewDidLoad() {
super.viewDidLoad()
}
}
you should add cellIdentifier from "Show the attributes inspector". Please fallow just like below snippet.
Firstly added below code to your-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath delagate method.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ResultCustomTableViewCell *cell = (ResultCustomTableViewCell *)[resultTableView dequeueReusableCellWithIdentifier:#"ResultTableViewCellIdentifier"];
...
//set the cell property
...
return cell;
}
and then jump the "Show the attributes inspector", While selected cell root view.
And then paste the same identifier name to identifier section in "Show the attributes inspector". in this case i use this ResultTableViewCellIdentifier.
And one more think. if you use custom cell just like this scenario, you must add below delegate metod. Because your custom cell height can be higher or smaller original tableview height. And Also you should register this nib in viewDidLoad.
- (void)viewDidLoad {
[resultTableView registerNib:[UINib nibWithNibName:#"ResultCustomTableViewCell" bundle:nil] forCellReuseIdentifier:[ResultCustomTableViewCell reuseIdentifier]];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat height = 0.0;
if (tableView == resultTableView){
height = 44.0f;
}
return height;
}
i hope, it'll fix your problem
CellIdentifier I bet your cellForRowAtIndexPath is returning nil.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
NSUInteger nodeCount = [self.entries count];
if (nodeCount == 0 && indexPath.row == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PlaceholderCellIdentifier] autorelease];
}
cell.detailTextLabel.text = #"Loading…";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (nodeCount > 0) {
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.name;
if (!appRecord.appIcon)
{
if (self.mytable_view.dragging == NO && self.mytable_view.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
That's probably why [UITableView _configureCellForDisplay:forIndexPath:] is failing... because cellForRowAtIndexPath is returning a null value and then configureCellForDisplay is expecting a UITableViewCell.
Register your cell in the - (void)viewDidLoad method using
[self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:#"Your Reuse Identifier"];
if your are using storyboards and use this if you are using a custom cell.
[self.tableView registerNib:UINib nibWithNibName:#"Your File Name.xib" bundle:nil forCellReuseIdentifier:#"Your Reuse Identifier"]

Resources