2015-05-14 114 views
1

我使用這個類叫SHLineGraphView,它的工作很好,但我有一個問題,他們沒有實現一個方法去除陰謀。現在我必須這樣做,但我不能完全確定正確的方法。SHGraphLineView刪除一個陰謀

這是他們畫的情節:

- (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]; 
} 

回答

1

因此,通過@Tejvansh辛格爾斯基的答案,我設法找到一個解決方案:

首先,我已經添加了這些2種新的方法來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點,但沒有標籤和其他所有與第一次繪製b相同的圖形uild圖:

- (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,它會指示這個特定圖的索引,y OU需要設置當您第一次建立的情節

SHPlot.h

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

享受! :)

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]; 
     } 
    } 
} 

希望它可以幫助你。

+0

謝謝你,但如果我想刪除只是一個具體的情節? –

+0

令人驚歎的答案的人,但問題是,當我設置一個valueForKey到CAShapeLayer,然後試圖獲得它的鍵值返回無 –

+0

如果我的答案幫助你,你可以upvote它。 :) – Tejvansh