Reputation: 826
I am just implementing a table view in my app. I have done this multiple times but this time the table cell shows the repeating data and speed of table scrolling is not good also. Just posting my code for table. Any help to prevent cell data repetition and scroll speed optimisation will be appreciated.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = [array count];
if (count%3 == 0)
{
return count;
}
else
{
count = count/3+1;
}
NSLog(@"Row count is%i",count);
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 490, 221)];
int x = 15;
int y = 15;
int p = 10;
int q = 10;
for (int i = 0; i < 3; i++)
{
if ( indexPath.row*3+i < [array count] )
{
UIImageView *img = [[UIImageView alloc] init];
UIButton *btn = [[UIButton alloc] init];
[img setImageWithURL:[NSURL URLWithString:[array objectAtIndex:indexPath.row*3+i]]
placeholderImage:[UIImage imageNamed:@"India.png"]
success:^(UIImage *image) {}failure:^(NSError *error){}];
img.frame = CGRectMake(x, y, 140, 201);
btn.frame = CGRectMake(p, q, 150, 211);
btn.tag = indexPath.row*3+i;
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_N.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_S.png"] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(Movie_detail:) forControlEvents:UIControlEventTouchUpInside];
[testView addSubview:img];
[testView addSubview:btn];
x = x+160;
p = p+160;
}
else
{
NSLog(@"No data");
break;
}
}
[cell addSubview:testView];
return cell;
}
The Things updated in cell is for the purpose to add 3 buttons in single cell. Nothing else.
Upvotes: 0
Views: 186
Reputation: 20021
SUGGESTION
Use custom cell
Fix :
Creating and adding the subview is to be included inside the braces where the cell is allocated
ie
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
//CREATING AND ADDING SUBVIEW SHOULD BE HERE
}
//Change in values is taken care here
REASON
Otherwise every time a subview is created,allocated all objects and added above when table is scrolled
REFER
Upvotes: 2
Reputation: 7573
The problem you are facing is that you add a UIView to every cell that comes into the screen. However you are reusing the cells so the old 'added' views are still on them. The repetition of the data is because there are multiple layers of testviews on a cell when you scroll.
You should either make a CustomCell that includes the testview that you are adding at every cellforrow: OR add the testview to the cellviews when the cell is still a nil-value so that if it gets reused you won't add yet another testview to the cell and they overlap. The examples of those are written in other answers here but are found on the web everywhere.
Not recommended but:
Another quick but dirty fix is to just remove all subviews from the cell (or any subview that you add the testview to) for(UIView *v in [cell(.contentView) subviews]){ [v removeFromSuperView]; }
Upvotes: 1
Reputation: 6342
hello this problem is normal when you are using dequeueReusableCell
just make change as i listed below in following methode..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
UIView *testView;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 490, 221)];
testView.tag = 111;
[cell addSubview:testView];
[testView release];//For Non ARC
}
else
{
testView = [cell.contentView viewWithTag:111];
for(UIView * vv in [testView subViews])
{
[vv removeFromSuperView];
}
}
int x = 15;
int y = 15;
int p = 10;
int q = 10;
for (int i = 0; i < 3; i++)
{
if ( indexPath.row*3+i < [array count] )
{
UIImageView *img = [[UIImageView alloc] init];
UIButton *btn = [[UIButton alloc] init];
[img setImageWithURL:[NSURL URLWithString:[array objectAtIndex:indexPath.row*3+i]]
placeholderImage:[UIImage imageNamed:@"India.png"]
success:^(UIImage *image) {}failure:^(NSError *error){}];
img.frame = CGRectMake(x, y, 140, 201);
btn.frame = CGRectMake(p, q, 150, 211);
btn.tag = indexPath.row*3+i;
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_N.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_S.png"] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(Movie_detail:) forControlEvents:UIControlEventTouchUpInside];
[testView addSubview:img];
[testView addSubview:btn];
x = x+160;
p = p+160;
}
else
{
NSLog(@"No data");
break;
}
}
return cell;
}
TRY THIS....
Upvotes: 0
Reputation: 4652
Repeating data in different cells might be due to same "CellIdentifier", try having different "CellIdentifier" for different cell view types. I can see different cell view types since you are having some condition block in your code.
static NSString *MyIdentifier;
MyIdentifier = @"Type1";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
MyIdentifier = @"Type2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
Upvotes: 0
Reputation: 12719
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 490, 221)];
int x = 15;
int y = 15;
int p = 10;
int q = 10;
for (int i = 0; i < 3; i++)
{
if ( indexPath.row*3+i < [array count] )
{
UIImageView *img = [[UIImageView alloc] init];
UIButton *btn = [[UIButton alloc] init];
[img setImageWithURL:[NSURL URLWithString:[array objectAtIndex:indexPath.row*3+i]]
placeholderImage:[UIImage imageNamed:@"India.png"]
success:^(UIImage *image) {}failure:^(NSError *error){}];
img.frame = CGRectMake(x, y, 140, 201);
btn.frame = CGRectMake(p, q, 150, 211);
btn.tag = indexPath.row*3+i;
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_N.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"Picframe_S.png"] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(Movie_detail:) forControlEvents:UIControlEventTouchUpInside];
[testView addSubview:img];
[testView addSubview:btn];
x = x+160;
p = p+160;
}
else
{
NSLog(@"No data");
break;
}
}
[cell addSubview:testView];
}
return cell;
}
You should not initialize anything outside the block where your cell
is initialized, because when you scroll
your tableview
the method cellForRowAtIndexPath
get called everytime, and your view testview
is getting created everytime..
Outside the cell initialization you should only update the values to be shown in the cell..
Hope above works..
Edited
But better approach I would suggest try to create a Custom Cell
so that you can easily access the components added to your cell to update their values as your tableview scrolls..
Thanks.
Upvotes: 0