I am loading a custom cell into a table view, and notice that my cell is not being re-used correctly. I am using a NSFetchedResultsController to pull the results from Core Data.
I am loading the cell from a nib. The cell identifier is setup in interface builder. The cells appear to get re-used because I am not creating a new cell everytime I scroll the table. However, the data is not being displayed correctly on the cells.
// BeerCell.h
#interface BeerCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIImageView *beerImage;
#property (nonatomic, strong) IBOutlet UILabel *displayBeerName;
#property (nonatomic, strong) IBOutlet UILabel *displayBeerType;
#end
// BeerCell.m
#implementation BeerCell
#synthesize beerImage;
#synthesize displayBeerName;
#synthesize displayBeerType;
#end
// Code where i'm setting up the cells for the tableView
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BeerCell";
BeerCell *cell = (BeerCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"BeerCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (BeerCell *) currentObject;
break;
}
}
[self configureCell:cell atIndexPath:indexPath];
}
return cell;
}
- (void)configureCell:(BeerCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
Beer *beer = (Beer *) [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.displayBeerName.text = beer.name;
}
Take the configureCell function call outside the if block.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BeerCell";
BeerCell *cell = (BeerCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"BeerCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (BeerCell *) currentObject;
break;
}
}
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
Related
I have created a custom cell FeatureCell which has 5 images in the row that will be called in the main view but when I call it I get empty row. So please where could be my problem?
I have googled about custom cell and I used the way that I have to use in the code below but nothing happen.
This is my FeatureCell.h
#interface FeatureCell : UITableViewCell{
IBOutlet UIImageView *img1;
IBOutlet UIImageView *img2;
}
#property (nonatomic, retain) UIImageView *img1;
#property (nonatomic, retain) UIImageView *img2;
#end
This is my FeatureCell.m
#implementation FeatureCell
#synthesize img,img1,img2,img3,img4;
#end
This is the my view-controller .m
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (section == 0) {
return [objectCollection count];
}
else{
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* cellIdentifier1 = #"FeatureCell";
FeatureCell *cell1 = (FeatureCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
if (cell1 == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellIdentifier1 owner:nil options:nil];
cell1 = (FeatureCell*)[nib objectAtIndex:0];
}
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CellIdentifier];
}
if ([indexPath section] == 0) {
containerObject = [objectCollection objectAtIndex:indexPath.row];
[[cell textLabel] setText:containerObject.store];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
else{
cell1.img1.image = [UIImage imageNamed:#"shower.png"];
cell1.img2.image = [UIImage imageNamed:#"parking.png"];
}
return cell;
}
You need to do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CellIdentifier];
}
containerObject = [objectCollection objectAtIndex:indexPath.row];
[[cell textLabel] setText:containerObject.store];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
} else {
static NSString* cellIdentifier1 = #"FeatureCell";
FeatureCell *cell1 = (FeatureCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
if (cell1 == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellIdentifier1 owner:nil options:nil];
cell1 = (FeatureCell*)[nib objectAtIndex:0];
}
cell1.img1.image = [UIImage imageNamed:#"shower.png"];
cell1.img2.image = [UIImage imageNamed:#"parking.png"];
return cell1;
}
}
I might have the if condition backwards so double check that.
This implementation:
#implementation FeatureCell
#synthesize img,img1,img2,img3,img4;
#end
Results in a cell with some accessor methods but no initialised instances. You need to implement an init method to create the instances or connect the variables (which you define as outlets) to the associated XIB file. Read this guide.
I also agree with the comments about the structure of how you're creating your different cell instances. It's very disorganised and you seem to be mixing up references. You should split things out into different methods or at least put the code for creating the cells inside the if statements so you can't typo the cell instance names.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) //not indexPath.section...fixed my problem
{
static NSString *CellIdentifier = #"MenuHeadingCustomCell";
MenuHeadingCustomCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell ==nil)
{
cell = [[MenuHeadingCustomCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
return cell;
}
else
{
static NSString* cellIdentifier1 = #"LevelViewCell";
LevelViewCell *cell1 =[tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
if (cell1 ==nil)
{
cell1 = [[LevelViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier1];
// row counts which dictionary entry to load:
_Dictionary=[_array objectAtIndex:indexPath.row];
cell1.LevelTitleText.text =[NSString stringWithFormat:#"%#",[_Dictionary objectForKey:#"LevelLabelText"]];
cell1.LevelSubText.text =[NSString stringWithFormat:#"%#",[_Dictionary objectForKey:#"LevelLabelSubText"]];
cell1.LevelThumb.image =[UIImage imageNamed:[_Dictionary objectForKey:#"LevelLabelThumb"]];
}
return cell1;
}
i'm using custom cell i learned in (This site). It's work in my old app but in this app i dont know why it's haven't work, when i run the above code he stuck with green error in line (NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CellIdentifier = #"CustomCell";
PCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (PCustomCell *) currentObject;
break;
}
}
}
P2Dict = [P2Rows objectAtIndex: indexPath.row];
cell.Contracts.text = [P2Dict objectForKey:#"Contracts"];
return cell;
}
http://ar2.co/SS2.png
custom cell xib .file take a tablecell.and in custom.m file implemented .and In view controller set the whole tableview through viewcontroller xib or programmatically .as ur choice .and set the delegate and datasourece methods.in datasource method written custom cell.code written below
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Custom";
CustomTableCell *cell = (CustomTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
UINib *nib = [UINib nibWithNibName:#"CustomTableCell" bundle:nil];
NSArray *arr = [nib instantiateWithOwner:nil options:nil];
cell = [arr objectAtIndex:0];
}
cell.textLabel.text =[arr objectAtIndex:indexPath.row];
}
Did you have UITableviewCell(PCustomCell) at CustomCell.xib?
You should show screenshot of the error here. It's will be helpful.
Your error states: "Could not load NIB in bundle named "CustomCell"". So there lies your problem.... what is your xib named?
refer a following process. How to create a custom table cell is one kind of.
VocaTableCell is my case. make a your CustomTableCell.
#import <UIKit/UIKit.h>
#interface VocaTableCell : UITableViewCell
{
UILabel *vocaLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *vocaLabel;
#end
#import "VocaTableCell.h"
#implementation VocaTableCell
#synthesize vocaLabel;
- (void)dealloc {
[vocaLabel release];
[super dealloc];
}
#end
Below code refer Befoe, Are you correctly make a customTableCell? below list check plz.
There are several ways to create about customTablecell.
My manner is very popular.
CustomTabelCell of File's Owner should be a NSObject.
(Very Important Default is Maybe UITableCell. You Must be a change File's Owner NSObject(NSObject mean is id type!))
CustomTableCell link a Object Class a your CustomTableCell Class.
Referencing Outlets link Not File's Owner, must be Your Directly link a CustomTableCell.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Custom";
CustomTableCell *cell = (CustomTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
UINib *nib = [UINib nibWithNibName:#"CustomTableCell" bundle:nil];
NSArray *arr = [nib instantiateWithOwner:nil options:nil];
cell = [arr objectAtIndex:0];
}
cell.textLabel.text =[arr objectAtIndex:indexPath.row];
}
I have the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
{
static NSString *CellID = #"FlourishCustomCell";
FlourishCustomCell *cell = (FlourishCustomCell *) [tableView dequeueReusableCellWithIdentifier:CellID];
if (cell == nil) {
cell = [[[FlourishCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID] autorelease];
cell.frame = CGRectMake(0, 0.0, 292.0, 30);
}
id <NSFetchedResultsSectionInfo> sectionInfo =
[[appDelegate.fetchedResultsController sections] objectAtIndex:indexPath.section];
NSLog(#"DATE:%#", [sectionInfo name]); //Output: March 25
cell.dateLabel.text=[sectionInfo name];
NSLog(#"header cell:%#", cell.dateLabel.text); //Output:header cell:(null)
return cell;
}
else {
static NSString *CellIdentifier = #"IdeaCustomCell";
IdeaCustomCell *cell = (IdeaCustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[IdeaCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.frame = CGRectMake(0, 0.0, 292.0, 70);
}
[self configureCell:cell atIndexPath:[self newIndexPathForIndexPath:indexPath]];
return cell;
}
}
The cells display and work fine for the else part (the IdeaCustomCell), but for some extremely frustrating reason, when I set the dateLabel of the FlourishCell, and then immediately try to access that value, I get a null value, even though I just set it! And the cell doesn't display on screen.
I tried overriding the setter method for dateLabel in the FlourishCustomCell class, and I put an NSLog statement there, but it never gets called for some reason.
I have absolutely no idea what could be causing this. I mean I'm allocating right then and there, but it's still giving me null. Any ideas?
You need to initialize the label
Solution 1: Initializing cell in code
#interface FlourishCustomCell : UITableViewCell
#property (nonatomic, retain) UILable * dateLabel;
#end
#implementation FlourishCustomCell
#synthesize dateLabel = _dateLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
{
_dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,300,50)];
[self.contentView addSubview:_dateLabel]
}
return self;
}
#end
Solution 2: Initializing cell from nib
#interface FlourishCustomCell : UITableViewCell
#property (nonatomic, retain) UILable * dateLabel;
#end
#implementation FlourishCustomCell
#synthesize dateLabel = _dateLabel;
- (id)init
{
self = [[[[NSBundle mainBundle] loadNibNamed:#"YOUR_NIB_NAME" owner:nil options:nil]
lastObject]
retain];
return self;
}
#end
EDIT: oops, forgot to return self on init method, updated the answer
i had the same problem when using nibs, this worked for me
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
NSString* nibFile = #"NibForCell";
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed: nibFile owner:nil options: nil];
cell = [topLevelObjects objectAtIndex: 0];
}
cell.cellText.text = #"test";
return cell;
}
just make sure you set the reuse identifier in the nib's properties
In CustomCell.m I define init method where I want to load cell from the IB:
- (id)init {
self = [super init];
if (self) {
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
self = [nib objectAtIndex:0];
}
return self;
}
In the MyTableViewController.m in the method cellForRowAtIndexPath I initialize my custom cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell=[[CustomCell alloc]init];
return cell;
}
Everything works as I expected but when I did Product -> Analyse I get
Returning 'self' while it is not set to the result of '[(super or self) init...]'
What am I doing wrong?
You are overwriting self (returned from super init) with the object returned from your array. If you want to load a custom cell from a nib, do it in your cellForRowAtIndexPath method, or create a convenience class method on your custom cell that loads from the nib:
In your cellForRowAtIndexPath:
cell = [CustomCell cell];
In your cell's implementation:
+(CustomCell*)cell
{
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
return [nib objectAtIndex:0];
}
EDIT - changed method name since new* indicates that a retained object will be returned.
Keep your init method as below, and do the linking in the Interface Builder
- (id)init {
self = [super init];
if (self) {
}
return self;
}
And
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell *) currentObject;
break;
}
}
}
}
What I am doing is
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Initialization code.
//
UITableViewCell *view = [[[NSBundle mainBundle] loadNibNamed:#"SmallCellView" owner:self options:nil] lastObject];
self.backgroundView = view;
}
return self;
}
then in the main class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
SmallCellView *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[SmallCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
For me this is working fine and in Product -> Analyse is not giving any warning or error
I met the same problem, I have fixed it by removing the code that like
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
return [nib objectAtIndex:0];
from the CustomView's definition init Method.
Put these code the at the place where you create the Custom.
I try to make a custom cell with a Uilabel and textfield
And i get this:
-> http://data.imagup.com/9/1119535256.png
But it's not given given my value ("Titre" & "Valeur" are generic):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"InscriptionCustomCell";
InscriptionCustomCell *cell = (InscriptionCustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"InscriptionCustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (InscriptionCustomCell *) currentObject;
break;
}
}
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(indexPath.section ==0)
{
[cell.titreCell setText:[model.listModuleInfoPerso objectAtIndex:indexPath.row]];
[cell.contenuCell setPlaceholder:[model.listModuleInfoPerso objectAtIndex:indexPath.row]];
}else {
[cell.titreCell setText:[model.listModuleInfoSupp objectAtIndex:indexPath.row]];
[cell.contenuCell setPlaceholder:[model.listModuleInfoSupp objectAtIndex:indexPath.row]];
}
return cell;
}
No error :S, an idea?
Put an NSLog in the [model.listModuleInfoPerso objectAtIndex:indexPath.row] so you can see what is coming out...
You probably forgot to hook up the label and the text field from Interface Builder to the properties in your InscriptionCustomCell subclass.
Here it seems that you haven't set the delegate for UITextField. So, please set delegate now and then you can access the TextField entry.