SHGraphLineView删除一个情节

时间:2015-05-14 08:26:16

标签: ios objective-c cashapelayer cgpath

我正在使用这个名为SHLineGraphView的课程并且它运作良好,但我有一个问题,即他们没有实施删除情节的方法。现在我必须这样做,但我无法找到正确的方法。

这是他们绘制情节的方式:

- (void)addPlot:(SHPlot *)newPlot;
{
  if(nil == newPlot) {
    return;
  }

  if(_plots == nil){
    _plots = [NSMutableArray array];
  }
  [_plots addObject:newPlot];
}

- (void)drawPlot:(SHPlot *)plot {

  NSDictionary *theme = plot.plotThemeAttributes;

  //
  CAShapeLayer *backgroundLayer = [CAShapeLayer layer];
  backgroundLayer.frame = self.bounds;
  backgroundLayer.fillColor = ((UIColor *)theme[kPlotFillColorKey]).CGColor;
  backgroundLayer.backgroundColor = [UIColor clearColor].CGColor;
  [backgroundLayer setStrokeColor:[UIColor clearColor].CGColor];
  [backgroundLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];

  CGMutablePathRef backgroundPath = CGPathCreateMutable();

  //
  CAShapeLayer *circleLayer = [CAShapeLayer layer];
  circleLayer.frame = self.bounds;
  circleLayer.fillColor = ((UIColor *)theme[kPlotPointFillColorKey]).CGColor;
  circleLayer.backgroundColor = [UIColor clearColor].CGColor;
  [circleLayer setStrokeColor:((UIColor *)theme[kPlotPointFillColorKey]).CGColor];
  [circleLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];

  CGMutablePathRef circlePath = CGPathCreateMutable();

  //
  CAShapeLayer *graphLayer = [CAShapeLayer layer];
  graphLayer.frame = self.bounds;
  graphLayer.fillColor = [UIColor clearColor].CGColor;
  graphLayer.backgroundColor = [UIColor clearColor].CGColor;
  [graphLayer setStrokeColor:((UIColor *)theme[kPlotStrokeColorKey]).CGColor];
  [graphLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];

  CGMutablePathRef graphPath = CGPathCreateMutable();

  double yRange = [_yAxisRange doubleValue]; // this value will be in dollars
  double yIntervalValue = yRange / INTERVAL_COUNT;

  //logic to fill the graph path, ciricle path, background path.
  [plot.plottingValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSDictionary *dic = (NSDictionary *)obj;

    __block NSNumber *_key = nil;
    __block NSNumber *_value = nil;

    [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
      _key = (NSNumber *)key;
      _value = (NSNumber *)obj;
    }];

    int xIndex = [self getIndexForValue:_key forPlot:plot];

    //x value
    double height = self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE;
    double y = height - ((height / ([_yAxisRange doubleValue] + yIntervalValue)) * [_value doubleValue]);
    (plot.xPoints[xIndex]).x = ceil((plot.xPoints[xIndex]).x);
    (plot.xPoints[xIndex]).y = ceil(y);
  }];

  //move to initial point for path and background.
  CGPathMoveToPoint(graphPath, NULL, _leftMarginToLeave, plot.xPoints[0].y);
  CGPathMoveToPoint(backgroundPath, NULL, _leftMarginToLeave, plot.xPoints[0].y);

  int count = _xAxisValues.count;
  for(int i=0; i< count; i++){
    CGPoint point = plot.xPoints[i];
    CGPathAddLineToPoint(graphPath, NULL, point.x, point.y);
    CGPathAddLineToPoint(backgroundPath, NULL, point.x, point.y);
    CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(point.x - 2.5, point.y - 2.5, 5, 5));
  }

  //move to initial point for path and background.
  CGPathAddLineToPoint(graphPath, NULL, _leftMarginToLeave + PLOT_WIDTH, plot.xPoints[count -1].y);
  CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave + PLOT_WIDTH, plot.xPoints[count - 1].y);

  //additional points for background.
  CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave + PLOT_WIDTH, self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE);
  CGPathAddLineToPoint(backgroundPath, NULL, _leftMarginToLeave, self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE);
  CGPathCloseSubpath(backgroundPath);

  backgroundLayer.path = backgroundPath;
  graphLayer.path = graphPath;
  circleLayer.path = circlePath;

  //animation
  CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  animation.duration = 1;
  animation.fromValue = @(0.0);
  animation.toValue = @(1.0);
  [graphLayer addAnimation:animation forKey:@"strokeEnd"];

  backgroundLayer.zPosition = 0;
  graphLayer.zPosition = 1;
  circleLayer.zPosition = 2;

  [self.layer addSublayer:graphLayer];
  [self.layer addSublayer:circleLayer];
  [self.layer addSublayer:backgroundLayer];

    NSUInteger count2 = _xAxisValues.count;
    for(int i=0; i< count2; i++){
        CGPoint point = plot.xPoints[i];
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.backgroundColor = [UIColor clearColor];
        btn.tag = i;
        btn.frame = CGRectMake(point.x - 20, point.y - 20, 40, 40);
        [btn addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
        objc_setAssociatedObject(btn, kAssociatedPlotObject, plot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    [self addSubview:btn];
    }
}

这就是我已添加的内容,但无法弄清楚如何实际删除该情节:

- (void)removePlot:(SHPlot *)plot
{
    if (nil == plot) {
        return;
    }

    if (_plots == nil) {
        return;
    }

    [_plots removeObject:plot];
    [self removePlotFromView:plot];
}

2 个答案:

答案 0 :(得分:1)

这是您需要在SHLineGraphView.m文件中添加的内容。 此方法将删除graphview上添加的所有图。

- (void)removeAllPlots {
    for (UIView *view in self.subviews) {
        view.layer.sublayers = nil;
        [view removeFromSuperview];
    }

    self.layer.sublayers = nil;
}

要删除特定的地块,首先需要为graphLayer,circleLayer和backgroundLayer提供唯一标记。

您可以通过在drawPlot:方法中添加以下代码来实现。

    [graphLayer setValue:[NSNumber numberWithInteger:[_plots indexOfObject:plot]]  forKey:@"PLTag"];
    [circleLayer.frame setValue:[NSNumber numberWithInteger:[_plots indexOfObject:plot]] forKey:@"PLTag"];
    [backgroundLayer setValue:[NSNumber numberWithInteger:[_plots indexOfObject:plot]] forKey:@"PLTag"];

然后,添加此方法以删除特定的情节:

- (void)removePlot:(SHPlot *)plot
{
    if (plot == nil)
        return;
    else if (_plots == nil)
        return;

    for (CALayer *layer in self.layer.sublayers) {
        if ([[layer valueForKey:@"PLTag"] isEqualToNumber:[NSNumber numberWithInteger:[_plots indexOfObject:plot]]]) {
            [layer removeFromSuperlayer];
        }
    }
}

希望它对你有所帮助。

答案 1 :(得分:1)

所以,通过@Tejvansh Singh Chhabra的回答,我设法找到了解决方案:

首先,我已将这两种新方法添加到SHGraphLineView.h

/**
 *  this methods will remove a plot from the graph.
 *
 *  @param plot the Plot that you want to remove from the Graph.
 */
- (void)removePlot:(SHPlot *)plot;


/**
 *  this methods will draw a new plot on the graph.
 *
 *  @param plot the Plot that you want to draw on the Graph.
 */
- (void)drawNewPlot:(SHPlot*)plot;

在主文件上实现它们:

- (void)removePlot:(SHPlot *)plot
{
    if (plot == nil) {
        return;
    }
    else if (_plots == nil) {
        return;
    }

    for (CALayer *layer in [self.layer.sublayers copy])
    {
        if ([layer valueForKey:@"PLTag"] != nil)
        {
            NSString *tag = [layer valueForKey:@"PLTag"];
            NSString *plotIndex = [NSString stringWithFormat:@"%ld", (long)plot.plotIndex];
            if ([tag isEqualToString:plotIndex])
            {
                [layer removeFromSuperlayer];
            }
        }
    }

    [_plots removeObject:plot];
}

- (void)drawNewPlot:(SHPlot*)plot
{
    if (nil == plot) {
        return;
    }

    if (_plots == nil) {
        _plots = [NSMutableArray array];
    }

    [_plots addObject:plot];
    [self xPointWithoutDrawingForPlot:plot];
    [self drawPlot:plot];
}

现在还有另一种方法可以为绘图创建x点,但是没有标签以及在第一次构建图形时使用它绘制的所有其他方法:

- (void)xPointWithoutDrawingForPlot:(SHPlot*)plot
{
    int xIntervalCount = _xAxisValues.count;
    double xIntervalInPx = PLOT_WIDTH / _xAxisValues.count;

    //initialize actual x points values where the circle will be
    plot.xPoints = calloc(sizeof(CGPoint), xIntervalCount);

    for(int i=0; i < xIntervalCount; i++)
    {
        CGPoint currentLabelPoint = CGPointMake((xIntervalInPx * i) + _leftMarginToLeave, self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE);
        CGRect xLabelFrame = CGRectMake(currentLabelPoint.x , currentLabelPoint.y, xIntervalInPx, BOTTOM_MARGIN_TO_LEAVE);
        plot.xPoints[i] = CGPointMake((int) xLabelFrame.origin.x + (xLabelFrame.size.width /2) , (int) 0);
    }
}

另一个重要的事情是在第一次抽奖时向地图的valueForKey对象添加CAShapeLayer,我们需要添加到此方法中:

- (void)drawPlot:(SHPlot *)plot;

这3行:

[graphLayer setValue:[NSString stringWithFormat:@"%ld", (long)plot.plotIndex]  forKey:@"PLTag"];
[circleLayer setValue:[NSString stringWithFormat:@"%ld", (long)plot.plotIndex] forKey:@"PLTag"];
[backgroundLayer setValue:[NSString stringWithFormat:@"%ld", (long)plot.plotIndex] forKey:@"PLTag"];

最后一件事,SHPlot课我们需要添加一个NSInteger来指示这个特定情节的索引,你需要在第一次构建情节时设置它

<强> SHPlot.h

/**
 *  index for plot for identification
 */
@property (assign, nonatomic) NSInteger plotIndex;

享受! :)