0

I have created a few labels on my tableview using custom UITableViewCell and interface builder. Now i am using some third party control called BEMLineGraph and i want to add it to my tableview cell using code. It also has a few delegates and data source methods. I am doing the following but the problem is that i get duplicate graphs and messed up data upon scrolling up and down.

ProductsTableViewCell.m

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.productGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:self.graphContainter.frame];
        //_myGraph.enableTouchReport = YES;
        self.productGraph.tag = 100;
        self.productGraph.animationGraphStyle = BEMLineAnimationNone;
        //_myGraph.enablePopUpReport = YES;
        self.productGraph.enableXAxisLabel = YES;
        self.productGraph.colorTouchInputLine = [UIColor whiteColor];
        self.productGraph.colorXaxisLabel = [UIColor darkGrayColor];
        self.productGraph.colorTop = [UIColor clearColor];
        self.productGraph.colorBottom = [UIColor clearColor];
        self.productGraph.colorLine = [UIColor colorWithRed:255.0/255.0 green:255.0/102.0 blue:255.0/102.0 alpha:1];
        self.productGraph.colorPoint = [UIColor lightGrayColor];
        [self addSubview:self.productGraph];
    }
    return self;
}

TableViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    ProductsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

        cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    cell.productGraph.frame = CGRectMake(0, 0, cell.graphContainter.frame.size.width, cell.graphContainter.frame.size.height);
    cell.productGraph.dataSource = self;
    cell.productGraph.delegate = self;

   //All the other stuff is set here and works well.

   }

- (NSInteger)numberOfPointsInLineGraph:(BEMSimpleLineGraphView *)graph
{
if (graph.tag == 100)
{
    return productDetail.count;
}
else
{
    return  numbers.count;
}
Rashid
  • 762
  • 1
  • 9
  • 30

2 Answers2

1

one thing wrong I can see your code:

  if (cell == nil)
    {
        cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }

it should be:

if (cell == nil)
{
    cell = [[ProductsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}

but this won't fix the problem of duplicate graphs

As you have subclassed the cell anyways, why don't you keep the delegate and datasource of the productGraph in the cell itself

Jatin
  • 1,668
  • 2
  • 16
  • 23
  • I have edited my code, it seems like cell is never nil! About the delegate and data source, i need to call them inside TableViewController.m since i do some data preparations and core data fetch there. – Rashid Aug 28 '15 at 16:42
  • keep the if statement there, thats important...whats happening in your case is that you are adding the subview to cell every time you scroll, hence you may be seeing duplicate graphs – Jatin Aug 28 '15 at 16:45
  • Why should i? With the if statement nothing appears. The statement (cell == nil) is always false. – Rashid Aug 28 '15 at 16:47
  • heres the answer to your why: http://stackoverflow.com/questions/3552343/uitableview-dequeuereusablecellwithidentifier-theory – Jatin Aug 28 '15 at 16:49
1

If you have registered the ProductsTableViewCell class with the UITableView, then dequeueReusableCellWithIdentifier: will create an object of that class for you, and call its initWithCoder: method (for cells defined in Interface Builder). Therefore, remove the call to your initWithStyle:reuseIdentifier: and do initialisation in the initWithCoder: method of ProductsTableViewCell instead.

Then, in your cellForRowAtIndexPath: do only that what is specific for that cell. What that is depends on the implementation of your Graph class, but it needs to make sure that the old graph is not visible anymore.

fishinear
  • 6,101
  • 3
  • 36
  • 84
  • If i remove initWithStyle:reuseIdentifier: how should i configure the graph? – Rashid Aug 29 '15 at 07:57
  • Do general initialisation in the init: method of the class, and configuration specific to a cell in the cellForRowAtIndexPath: – fishinear Aug 29 '15 at 08:52
  • Ok Thanks for the help. Let me explain the situation a little bit more. I have created my cell using a custom uitableviewcell. The labels and imageviews on each cell is created using interface builder. But the graph i am using can only be added programmatically (or at least thats what i think). The graph has also a few delegates and datasources. Now i have trouble setting the graphs correctly. The graphs are dupliacted on top of each other. – Rashid Aug 29 '15 at 09:04
  • Ah. For Cells defined in InterfaceBuilder, you'll need to do your custom initialisation of the graph in the initWithCoder: or awakeFromNib: methods instead of init:. See http://stackoverflow.com/questions/16952935/styling-custom-uitableviewcell-in-initwithcoder-not-working for some background. I've changed the answer. – fishinear Aug 29 '15 at 12:32
  • Just thought about something else. Make sure that the background of your graph is not transparent. Otherwise the old graph will likely show through. – fishinear Aug 29 '15 at 12:46