I want to display custom cells, but my code is only displaying one custom table cell at once.. what am I doing wrong?
I have a UIViewController nib set up with my UITableView inside the UIView. Also there is a UITableViewCell in the nib, whose class is CustomCell (a subclass of UITableViewCell). Both the UITableView and the Cell are #sythesized IBOutlet #properties.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"CellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // CustomCell is the class for standardCell
if (cell == nil)
{
cell = standardCell; // standardCell is declared in the header and linked with IB
}
return cell;
}
You can use below sample code;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"CellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // CustomCell is the class for standardCell
if (cell == nil)
{
NSArray *objectList = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in objectList) {
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell*)currentObject;
break;
}
}
}
return cell;
}
You should create a new cell every time dequeueReusableCellWithIdentifier return nil
Usually it should looks like
...
if (cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:nil options:nil] objectAtIndex:0]
}
...
p.s. instead of objectAtIbndex: you can traverse through the array returned and use isKingOfClass:[MyCell class] to find the cell
The cell must have its content set for the given index path, even if the cell itself is dequeued, e.g.:
if (cell == nil) {
/* instantiate cell or load nib */
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
/* configure cell for a given index path parameter */
if (indexPath.row == 123)
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
else
cell.accessoryType = nil;
/* etc. */
return cell;
If the cell == nil then you need to instantiate a new UITableViewCell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"CellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// Instantiate a new cell here instead of using the "standard cell"
CustomCell *cell= [[[CustomCell alloc] init reuseIdentifier:CellIdentifier] autorelease];
// Do other customization here
}
return cell;
}
Related
I am new in iPhone development. I am using UItableview for showing list.
And able to show all items successfully.
But they changed when I scroll tableview.
Please help me.
Try this code in cellForRowAtIndexPath method of tableview
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Please give me more information to show your case clearly.
Have a look at this function first because all rows are generated from here!
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
return cell;
}
Check whether each row is exist,unless just reuse it later.
I have a prototype cell with label
#property (nonatomic, strong) IBOutlet UILabel *itemName;
declared in class ECOMAdmPanelViewCell and the class is set for the cell in Identity inspector. The outlet itemName - Label is created.
In this function
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"admPanelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
cell = [[ECOMAdmPanelViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.itemName.text = [items objectAtIndex:indexPath.row];
// Configure the cell...
return cell;
}
I get an error message property 'itemName' not found on object of type 'UITableViewCell'. Can anyone tell me what's wrong?
Change your this line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
with this
ECOMAdmPanelViewCell *cell = (ECOMAdmPanelViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Try this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"admPanelCell";
ECOMAdmPanelViewCell *cell = (ECOMAdmPanelViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
cell = [[ECOMAdmPanelViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.itemName.text = [items objectAtIndex:indexPath.row];
// Configure the cell...
return cell;
}
or use this:
(ECOMAdmPanelViewCell *)cell.itemName
Here tableview after scrolling 2 3 times full up and down add images to all cells. Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:#"HomeCell"];
if (cell == nil) {
cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"HomeCell"] ;
}
VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
if ([venueObj.imagesArray count] > 0) {
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
}
venueObj = nil;
return cell;
}
Any idea what's happening here?
Image is only in one object, on first load it shows one cell with image, but after scrolling it starts showing images on other cell too.
Solved it like this, first i set the lblName frame to its original position, so it reset its position everytime the cell is used
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:#"HomeCell"];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"HomeCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (HomeCell *) currentObject;
break;
}
}
}
VenueDC *venueObj = nil;
venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
[cell.ivVenue setHidden:YES];
cell.lblName.frame = CGRectMake(20 , 19, 250, 20);
if (venueObj.ivVenue) {
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
}
return cell;
}
UITableViewCells get reused, which is what the dequeueReusableCellWithIdentifier: method does. To save memory the UITableView only instantiates as many cells as it is possible to see at any given point, and then just keeps on reusing them. Because of this you should always clean up your cells before reuse, that is reset all its content to nil.
If you are using a custom table view like in your case HomeCell then override -(void)prepareForReuse and set up the image to nil there.
It is happening because your cell is reuse so write this code:
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"HomeCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (HomeCell *) currentObject;
break;
}
}
}
You Need to add only one line in cellForRowAtIndexPath
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
And change
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:#"HomeCell"];
if (cell == nil) {
cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"HomeCell"] ;
}
VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
[cell.ivVenue setImage:nil];
if ([venueObj.imagesArray count] > 0) {
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
}
venueObj = nil;
return cell;
}
You need an else statement:
else {
venueObj = nil;
}
I want to have a custom cell in my UITableview. I have tried it with the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (CustomCell*)view;
}
}
}
[cell setLabelText:[daten objectAtIndex:indexPath.row]];
return cell;
}
But I am getting an exception on that line:
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
I'm almost sure that you have lost connection in your XIB file. If commentLabel is still exists you should either delete it and create a new outlet or check the outlets section and delete extra connection and all will be alright!!
EDIT:
This error occurs when you have two outlets connected to the same label in IB.
This is how I made my custom cell and called it from the class :-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:[cell reuseIdentifier]];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = customCell;
customCell = nil;
}
// Configure the cell.
cell.serialLabel.text = [[NSNumber numberWithInt:indexPath.row+1]stringValue];
cell.textLabel.textColor=[UIColor whiteColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
if u are not using the latest ios SDK, make sure that u have written
#synthesize commentLabel;
in CustomCell
Try cleaning the build folder, or try Simulator -> Reset Content and Settings.
i have created a custom UITableViewCell, but when I dequeue the cell, sometimes it throws an NSInvalidArgumentException:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell lblMonth]: unrecognized selector sent to instance 0x6aa7df0
Now, my custom UITableViewCell does have an attribute lblMonth, so I am confused why it is throwing this error. Below is the code I use to dequeue the cell:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell;
cell = [(CustomCell*)[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"New_Phone" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[CustomCell class]])
{
cell = (CustomCell *)currentObject;
break;
}
}
}
CGFloat emival= emi;
CGFloat curinterest = balarray[indexPath.row] * interset;
if(indexPath.row == tenure){
emival = balarray[indexPath.row-1] + curinterest;
}
CGFloat curamnt = emival - curinterest;
balarray[indexPath.row]=balarray[indexPath.row]-curamnt;
[[cell lblMonth]setText:[NSString stringWithFormat:#"%d", indexPath.row+1]];
[[cell lblEMI]setText:[NSString stringWithFormat:#"%.f", emival]];
[[cell lblInterest]setText:[NSString stringWithFormat:#"%.f", curinterest]];
[[cell lblPrinicipal]setText:[NSString stringWithFormat:#"%.f", curamnt]];
[[cell lblBalance]setText:[NSString stringWithFormat:#"%.f", balarray[indexPath.row]]];
return cell;
}
Please help me over this...Thanks in Advance
The problem lies in following line of code:
cell = [(CustomCell*)[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
you should use
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Because when you check for nil it will never be nil(it will not go in if case) and a UITableViewCell object is created not the custom cell object. But thats not what you want. You want to load cell from nib and dequeue it for reuse.
See Your Code you need to change FewLines with Given Lines and rest stays same.
This is Because you are making some Mistakes just Compare your code with below Code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
//below Line get cells if they Cells Exist.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//below Line Checking precrated Cells Exist
if (cell == nil) {
cell = [(CustomCell*)[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}