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.
Related
Please help me with UITableViewCells.
I have followed many tutorials and sites but didn't get my problem solved.
I have tried to make a simpleCustomCells app but data are not loaded in the table view.
1.I have a table view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [NSArray arrayWithArray:[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil]];
for(id obj in nib)
{
if([obj isKindOfClass:[UITableViewCell class]])
{
cell = (CustomCell *)obj;
}
}
}
cell.label.text = #"hello";
return cell;
}
Also tried
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
"within if(cell==nill)"
2.I have created CustomCell : UITableViewCell with only a UILabel outlet. Changed CustomCell.xib identifier's name.
When I run this app I get this kind of error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x71627f0> setValue:forUndefinedKey:]: this class
is not key value coding-compliant for the key label.
Please Help me with this issue, where am I going wrong.
Ok, I think I got where you are getting stuck.
Step 1 : Disconnect the outlet UILabel from the xib file.
Step 2 : Go to your xib file and you will see your objects list on the left hand side of the xib file.
Step 3 : Take your mouse pointer just below where objects is written. You will find Custom Cell written.
Step 4 : Press ctrl and drag it to the label and now Connect the Outlet to label.
Step 5 : Clean your program and Run it again.
All the best. If you still have doubts, I will elaborate. :)
I think you should add like this, I hope it works
static NSString *CellIdentifier = #"Cell";
customcellCell *cell = (customcellCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; <- set your customclass in this line.
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"customviewcell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.label.text = #"hello";
return cell;
Use following way :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ContactListCell *contactCell;
NSString *contactCellID = [NSString stringWithFormat:#"ContactCell%d%d",indexPath.row,indexPath.section];
contactCell = (ContactListCell *)[tableView dequeueReusableCellWithIdentifier:contactCellID];
if(!contactCell) {
contactCell = [[ContactListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:contactCellID];
contactCellID = nil;
}
strName = #"First name";
contactCell.lblFirstName.text = [strName capitalizedString];
return contactCell;
}
For Custom cell .h file
#interface ContactListCell : UITableViewCell {
UILabel *lblFirstName;
}
#property (strong, nonatomic) UILabel *lblFirstName;
#end
For Custom cell .m file
#implementation ContactListCell
#synthesize lblFirstName;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
lblFirstName = [[UILabel alloc]initWithFrame:CGRectMake(kxiPadFirstNameCellLandscape, kyiPadFirstNameCellLandscape, kiPadFirstNameCellWidthLandscape, kiPadFirstNameCellHeightLandscape)];
lblFirstName.backgroundColor= [UIColor clearColor];
lblFirstName.numberOfLines = 0;
lblFirstName.textColor = kCustomCellFontColor;
[self.contentView addSubview:lblFirstName];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
Why not give you're cell an identifier and instantiate it with dequewithreusableidentifier?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[AanbodTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.Label.text =#"Hello"
return cell;
}
i would also refer to this very good tutorial http://www.appcoda.com/customize-table-view-cells-for-uitableview/
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;
}
In my app I have custom UITableViewCell, and I have UIStepper and UILabel in the custom cell. I don't know how to check which stepper was clicked. So is it a way to know from which cell stepper was clicked?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
if ([nib count] > 0) {
cell = self.tbcell;
}
}
return cell;
}
An alternative is:
In the method that gets fired when the UIStepper value changes (e.g. #max_, above), you can do the following:
- (IBAction)stepperValueDidChanged:(UIStepper *)sender {
UITableViewCell *cell = (UITableViewCell *)[[sender superview] superview];
// assuming your view controller is a subclass of UITableViewController, for example.
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
}
[step addTarget:self action:#selector(someAction:) forControlEvents:UIControlEventValueChanged];
- (void) someAction:(UIStepper *) stepper {
NSLog(#"stepper clicked");
}
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];
}
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;
}