选择单元格后,在不同单元格上复制视图

时间:2015-08-05 06:15:39

标签: ios objective-c uitableview

我有一个tableviewcontroller和一个自定义单元格。我想要做的是当我点击单元格时,单元格应该被挖掘,并且视图(实际上是图形视图)应该在单元格内部进行子视图。现在的问题是一切正常,但图表也在其他一些单元格上重复。

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

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

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (cell == nil)
    {
        NSLog(@"empty cell");
    }

    //Product Label
    cell.productNameLabel.text = @"something";

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    indexPathforChart = indexPath;
    [self performSelector:@selector(addChart:) withObject:indexPath afterDelay:0.2];
    [tableView beginUpdates];
    [tableView endUpdates];

    [tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
}

-(void)addChart:(NSIndexPath*)indexPath
{   
        BEMSimpleLineGraphView *myGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:CGRectMake(0, 60, screenSize.width, 200)];
        myGraph.dataSource = self;
        myGraph.delegate = self;
        myGraph.interpolateNullValues = YES;
        myGraph.enableTouchReport = YES;
        myGraph.tag = 100;
        myGraph.animationGraphStyle = BEMLineAnimationDraw;
        myGraph.enablePopUpReport = YES;
        myGraph.enableXAxisLabel = YES;
        myGraph.colorXaxisLabel = [UIColor darkGrayColor];

        ProductsTableViewCell *cell = (ProductsTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
        [cell.contentView addSubview:myGraph];
        [cell setNeedsLayout];
        [cell setNeedsDisplay];
        myGraph.colorTop = [UIColor clearColor];
        myGraph.colorBottom = [UIColor clearColor];
        myGraph.colorLine = [UIColor darkGrayColor];
        myGraph.colorPoint = [UIColor lightGrayColor];    
    }

2 个答案:

答案 0 :(得分:2)

这是由细胞重复使用引起的。

ProductsTableViewCell *cell = (ProductsTableViewCell*)[self.tableView
cellForRowAtIndexPath:indexPath];
[cell.contentView addSubview:myGraph];

在滚动表格视图时,当某个其他索引路径重复使用该单元格时,您在单元格中添加了myGraph作为子视图而不删除它。

最合适的方法应该是在单元格内部使用自定义视图来绘制图形,而不是在需要时添加/删除图形视图。为了滚动性能,您还可以缓存图形,以防在用户来回滚动时使用它。

答案 1 :(得分:1)

单元格被重用,因此在加载新单元格之前,您应该实现方法prepareForReuse并添加/删除或隐藏/取消隐藏单元格所需的视图。

基本上,ProductsTableViewCell应该实现方法prepareForReuse。根据您的代码删除BEMSimpleLineGraphView的最简单方法是:

- (void) prepareForReuse{
  UIView *v = [cell.contentView viewWithTag:100];
  if ( v ) {
    [v removeFromSuperView];      
  }
}

但是,我不考虑使用viewWithTag是最好的解决方案,所以我会将代码更改为类似于:

<强> tableviewcontroller

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ProductsTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [tableView beginUpdates];
    [cell addChart];
    [tableView endUpdates];

    [tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
}

<强> ProductsTableViewCell

@interface DLSContactUsViewController ()
    @property (strong,nonatomic) BEMSimpleLineGraphView *myGraph;

@end


-(void)addChart
{   
    if ( ![self.myGraph isDescendantOfView] ){
       [self.contentView addSubview:self.myGraph];
       [self setNeedsLayout];
       [self setNeedsDisplay];
    }
}

- (BEMSimpleLineGraphView*) myGraph{
    if ( !_myGraph ) {
      _myGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:CGRectMake(0, 60, screenSize.width, 200)];
      _myGraph.dataSource = self;
      _myGraph.delegate = self;
      _myGraph.interpolateNullValues = YES;
      _myGraph.enableTouchReport = YES;
      _myGraph.tag = 100;
      _myGraph.animationGraphStyle = BEMLineAnimationDraw;
      _myGraph.enablePopUpReport = YES;
      _myGraph.enableXAxisLabel = YES;
      _myGraph.colorXaxisLabel = [UIColor darkGrayColor];
      _myGraph.colorTop = [UIColor clearColor];
      _myGraph.colorBottom = [UIColor clearColor];
      _myGraph.colorLine = [UIColor darkGrayColor];
      _myGraph.colorPoint = [UIColor lightGrayColor];  
    }
    return _myGraph;
}

- (void) prepareForReuse{
  if ( [self.myGraph isDescendantOfView] && !self.isSelected ) {
    [myGraph removeFromSuperView];  
  }    
}