Reputation: 1681
I have a UITableView
where the data displays but when it scrolls the data (UILabel
) either disappear or they are added over and over again on top of each other.and every time if i scroll every cell exchange data.
here's my cellForRowAtIndexPath:
code
-(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];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// configure the cell's background
UIImageView *gradient = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gradient"]];
[cell.contentView addSubview:gradient];
// configure the cell's label
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 130, 300, 44)];
// grab a reference to the label's text from the tableData
nameLabel.text = [name objectAtIndex:indexPath.row];
nameLabel.textColor = [UIColor blackColor];
nameLabel.font = [UIFont fontWithName:@"DIN-Bold" size:12];
nameLabel.backgroundColor = [UIColor clearColor];
// set the autoReiszing mask -- this way if the label spills over the editing
// [icon?] then the text will trail off in ...
nameLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:nameLabel];
// configure the cell's label
UILabel *tableTextViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 80, 220, 50)];
// grab a reference to the label's text from the tableData
tableTextViewLbl.text = [message objectAtIndex:indexPath.row];
tableTextViewLbl.textColor = [UIColor blackColor];
tableTextViewLbl.font = [UIFont fontWithName:@"DIN" size:10];
tableTextViewLbl.backgroundColor = [UIColor clearColor];
tableTextViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:tableTextViewLbl];
// configure the cell's label
UILabel *tableTimeStampViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 200, 50)];
// grab a reference to the label's text from the tableData
tableTimeStampViewLbl.text = [timeStamp objectAtIndex:indexPath.row];
tableTimeStampViewLbl.textColor = [UIColor lightGrayColor];
tableTimeStampViewLbl.font = [UIFont fontWithName:@"DIN" size:7];
tableTimeStampViewLbl.backgroundColor = [UIColor clearColor];
tableTimeStampViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:tableTimeStampViewLbl];
// UIImageView *image;
// UIImage *image1=[UIImage imageNamed:@"rest.png"];
// image=[[UIImageView alloc]initWithImage:image1];
// image.frame=CGRectMake(10,30,40,30);
//
// [cell.contentView addSubview:image];
//
return cell;
}
Upvotes: 0
Views: 1536
Reputation: 6427
First of all you need to understand how UITableView works. Actually UItableView Cell concept is that every time you scroll the table view, it's not creating new cell for you, it's just reusing the cell, with help of cellIdentifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
And that time we need to just update the data for cell. That's it, simply better. You can see that below:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UILabel *nameLabel = nil;
UILabel *tableTextViewLbl= nil;
UILabel *tableTimeStampViewLbl= nil;
//Here we are , reuse the cells...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// configure the cell's background
UIImageView *gradient = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gradient"]];
[cell.contentView addSubview:gradient];
// configure the cell's label
nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 130, 300, 44)];
// grab a reference to the label's text from the tableData
nameLabel.textColor = [UIColor blackColor];
nameLabel.font = [UIFont fontWithName:@"DIN-Bold" size:12];
nameLabel.backgroundColor = [UIColor clearColor];
nameLabel.tag = 111;//Giving this component to tag so we can access it
// set the autoReiszing mask -- this way if the label spills over the editing
// [icon?] then the text will trail off in ...
nameLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell.contentView addSubview:nameLabel];
// configure the cell's label
tableTextViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 80, 220, 50)];
tableTextViewLbl.textColor = [UIColor blackColor];
tableTextViewLbl.font = [UIFont fontWithName:@"DIN" size:10];
tableTextViewLbl.backgroundColor = [UIColor clearColor];
tableTextViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
tableTextViewLbl.tag = 222;//Giving this component to tag so we can access it
[cell.contentView addSubview:tableTextViewLbl];
// configure the cell's label
tableTimeStampViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 200, 50)];
tableTimeStampViewLbl.textColor = [UIColor lightGrayColor];
tableTimeStampViewLbl.font = [UIFont fontWithName:@"DIN" size:7];
tableTimeStampViewLbl.backgroundColor = [UIColor clearColor];
tableTimeStampViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
tableTimeStampViewLbl.tag = 333;//Giving this component to tag so we can access it
[cell.contentView addSubview:tableTimeStampViewLbl];
}
nameLabel = (UILabel*)[cell.contentView viewWithTag:111];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
nameLabel.text = [name objectAtIndex:indexPath.row];
tableTextViewLbl = (UILabel*)[cell.contentView viewWithTag:222];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
// grab a reference to the label's text from the tableData
tableTextViewLbl.text = [message objectAtIndex:indexPath.row];
tableTimeStampViewLbl = (UILabel*)[cell.contentView viewWithTag:333];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
// grab a reference to the label's text from the tableData
tableTimeStampViewLbl.text = [timeStamp objectAtIndex:indexPath.row];
return cell;
}
Upvotes: 0
Reputation: 635
Just add following code
NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews];
for (UILabel *subview in subviews)
{
[subview removeFromSuperview];
}
[subviews release];
subviews = nil;
After -
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
And then add your code.
Upvotes: 1
Reputation: 1227
Use this way
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
But taking custom cell is the best answer. check this link gives best solution to custom cell
Upvotes: -2
Reputation:
Before You follow my Answer i want to tell you that following code is bad for memory management because it will create new cell for each rows of UITableView
, so be careful for it.
But it is better to use, When UITableView
Have Limited rows (about 50-100 may be ) then following code is helpful in your case, use it if is it suitable for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// Put your code here
}
return cell;
}
If you have limited rows then this is best code for you.
Upvotes: 0
Reputation: 14304
You are creating a UILabel instance for every time a cell gets loaded/reloaded into view. This is not how it's done. Instead - add the UILabel as a property (probably an IBOutlet) in a UITableView subclass and alter it in cellForRowAtIndexPath:
.
So you would have a new class, inheriting from UITableViewCell - let's call it MyCustomCell.
In MyCustomCell.h:
@interface MyCustomCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end
MyCustomCell.xib will define the UILabel position and configuration and of course needs to be associated with the nameLabel property.
In cellForRowAtIndexPath, rather than instantiating a new UILabel, you would just refer to cell.nameLabel and change the text. Be sure to define a resuseIdentifier for the cell class in interface builder and instantiate it using:
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
if (!cell) {
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyIdentifier"];
}
Upvotes: 3