0

I have a custom table view cell class. I dynamically create uiviews and uilabels and uiimageview to cell and alloc and init them with frame.contentView. But on scroll because of reuse they get overlapped and label's text and other properties get overlapped.

meteors
  • 1,747
  • 3
  • 20
  • 40
  • Could you please clarify, are the cells overlapping each other or are the labels and uiimageviews appearing more than once in a single cell? – JoGoFo Apr 09 '15 at 00:55
  • overlapping and also seeing extra views in case the previous cell did add extra views and latter has lesser views – meteors Apr 09 '15 at 01:10

4 Answers4

0

If you reuse cells, you almost entirely responsible for resetting their content before reuse. This is a problem that is still not sufficiently explained in the SDK documentation, in my opinion.

That means, after calling [dequeueReusableCellWithIdentifier], you should do things like:

1) Set/Reset color, font, and text on textLabel and detailTextLabel, if you ever touch these.

2) Adjust accessoryType.

3) Adjust frame and backgroundColors.

4) Remove all non-standard subviews. I usually code like this:

for (UIView *subView in cell.contentView.subviews) {
    if (subView == cell.textLabel) continue;
    if (subView == cell.imageView) continue;
    if (subView == cell.detailTextLabel) continue;
    [subView removeFromSuperview];
}

And so on. Anything that can get touched for a particular reuse identifier should be reset to a zero-state.

robinkunde
  • 1,005
  • 9
  • 12
  • unfortunately I don't have anything cell.textlabel or any other variables. I use a for loop to add subviews as required. and allocate them each and every time. – meteors Apr 09 '15 at 01:26
  • Those were just examples. Try the code in 4) that removes all extra subviews before adding new ones. – robinkunde Apr 09 '15 at 01:33
0

Check rowsize of table and row size of custom cell should be same to get proper view.

Check and alloc cell like this after reuse of tabeview cell.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
   static NSString *cellIdentifier = @"SampleCell";

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    NSLog(@"cai no init da cell");
// change style according to yours..
}

return cell

}

Bhoomi Jagani
  • 2,413
  • 18
  • 24
0

It sounds like you are adding child views to the cell inside the tableview:cellForRowAtIndexPath: method. As the cells are being reused, the views from a previous use already exist in the cell, and you are ignoring those new views and just adding more.

The correct way is to add the views during the initialisation of the cell, then just set the values of the views in the tableview:cellForRowAtIndexPath: method.

You should use a custom class inheriting from UITableViewCell and create properties for the views you want to add (so they can be accessed in tableview:cellForRowAtIndexPath:). You can then either add the views in the init call for the custom class, or use an XIB or prototype cell to add the views and hook them up to the properties as IBOutlets.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyModelObject* myObject = myObjects[indexPath.row];

    if (myObject.images.count == 1) {
        MyCustomTableViewCellOne *cell = (MyCustomTableViewCellOne*) [self.tableView dequeueReusableCellWithIdentifier:@"MyCustomTableViewCellOneIdentifer" forIndexPath:indexPath]; 

        cell.title = @"Some item";
        cell.imageView.image = [UIImage imageNamed:@"image.png"];
        return cell;
    } else {
        MyCustomTableViewCellTwo *cell = (MyCustomTableViewCellTwo) [self.tableView dequeueReusableCellWithIdentifier:@"MyCustomTableViewCellTwoIdentifer" forIndexPath:indexPath]; 

        cell.title = @"Some item";
        cell.imageView.image = [UIImage imageNamed:@"image.png"];
        cell.imageView2.image = [UIImage imageNamed:@"image2.png"];
        return cell;
    }
}

MyCustomTableViewCellOne.h:

@interface MyCustomTableViewCellOne : UITableViewCell

@property (strong, nonatomic) IBOutlet UILabel *title;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;

@end

MyCustomTableViewCellTwo.h:

@interface MyCustomTableViewCellTwo : UITableViewCell

@property (strong, nonatomic) IBOutlet UILabel *title;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) IBOutlet UIImageView *imageView2;

@end
JoGoFo
  • 1,928
  • 14
  • 31
  • But how do I create properties? For one cell I want to add 4 subview and 2 for other. The number of subview does not remain fixed. – meteors Apr 09 '15 at 01:23
  • If you have a few different layouts you want to use, create prototype cells and custom classes for each of those layouts. If there are way too many to create or it is going to be different every single time, then as @rkunde suggested, maybe the best approach is to reset the cell each time by removing all the subviews. – JoGoFo Apr 09 '15 at 01:30
  • I have updated my solution with some example code if you go with the custom class approach. You will need to replace the logic for determining which cell type is used. – JoGoFo Apr 09 '15 at 01:46
  • Exactly @JoGoFo what if I had 100 imageviews in one cell and 200 in other? – meteors Apr 09 '15 at 04:14
0

Finally solved the problem by using tag for each subview. After getting the view by tag from it's parent view, if view is not present only then I reallocate and addSubView. This solved the issue.

meteors
  • 1,747
  • 3
  • 20
  • 40