Having position problem in Core Text animation - ios

I'm trying to convert following (link) swift code in objective c.
https://stackoverflow.com/a/49100870/797196
CTFontRef helveticaBold = CTFontCreateWithName( CFSTR("Helvetica-Bold"), 60.0, NULL);
NSString* unicodeString =#"Window Title";
CGColorRef color = [UIColor blueColor].CGColor;
NSNumber* underline = [NSNumber numberWithInt:
kCTUnderlineStyleSingle|kCTUnderlinePatternDot];
NSDictionary* attributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)helveticaBold, (NSString*)kCTFontAttributeName,
color, (NSString*)kCTForegroundColorAttributeName,
underline, (NSString*)kCTUnderlineStyleAttributeName, nil];
NSAttributedString* stringToDraw = [[NSAttributedString alloc]
initWithString:unicodeString
attributes:attributesDict];
CGMutablePathRef letters = CGPathCreateMutable();
// CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)#"Avenir",20,nil);
CTLineRef lines = CTLineCreateWithAttributedString((CFAttributedStringRef)stringToDraw);
CFArrayRef runArray = CTLineGetGlyphRuns(lines);
CAShapeLayer *pathLayer = [CAShapeLayer layer];
for (int i = 0; i < CFArrayGetCount(runArray); i++) {
CTRunRef run = CFArrayGetValueAtIndex(runArray, i);
CFDictionaryRef dictRef = CTRunGetAttributes(run);
NSDictionary *dict = (__bridge NSDictionary*)dictRef;
CTFontRef runFont = (__bridge CTFontRef)(dict[(NSString*)kCTFontAttributeName]);
for (int runGlyphIndex=0; runGlyphIndex<CTRunGetGlyphCount(run); runGlyphIndex++) {
CGGlyph glyph;
CGPoint position = CGPointZero;
CTRunGetGlyphs(run, CFRangeMake(runGlyphIndex, 1), &glyph);
CTRunGetPositions(run, CFRangeMake(runGlyphIndex, 1), &position);
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, nil);
CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
CGPathAddPath(letters, &t, letter);
CAShapeLayer *pathL = [CAShapeLayer layer];
// pathLayer.frame = _pathLayerView.bounds;
CGRect rect = CGPathGetBoundingBox(letter);
rect.origin = position;
pathL.frame = rect;
pathL.geometryFlipped = true;
pathL.path = letter;
pathL.strokeColor = UIColor.blueColor.CGColor;
pathL.fillColor = UIColor.redColor.CGColor;
pathL.lineWidth = 4.0;
pathL.lineJoin = kCALineJoinBevel;
CABasicAnimation *stroke = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
stroke.fromValue = #(0.0);
stroke.duration = 3.0f;
stroke.repeatCount = 0;
[pathL addAnimation:stroke forKey:nil];
[pathLayer addSublayer:pathL];
}
}
[_pathLayerView.layer addSublayer:pathLayer];
But the problem is letters alignment is not in required position. "i","n","o" letters y position starts from the top. & its obvious, because I didn't use the position of the letters.
I find out the positions of the letters using CTRunGetPositions, but I dont know how to use it or where to use it.

Related

Draw letter(text) with UIBezierPath single line

I am using this and this for reference. I am new for using UIBezierPath, and i want to draw path on character(letter) code i am using is as follow.
CGMutablePathRef letters = CGPathCreateMutable();
CTFontRef font = CTFontCreateWithName(CFSTR("Courier New"), 200.0f, NULL);
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:CFBridgingRelease(font), kCTFontAttributeName,nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:#"B"
attributes:attrs];
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
CFArrayRef runArray = CTLineGetGlyphRuns(line);
// for each RUN
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
{
// Get FONT for this run
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
// for each GLYPH in run
for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)
{
// get Glyph & Glyph-data
CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
CGGlyph glyph;
CGPoint position;
CTRunGetGlyphs(run, thisGlyphRange, &glyph);
CTRunGetPositions(run, thisGlyphRange, &position);
// Get PATH of outline
{
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
CGPathAddPath(letters, &t, letter);
CGPathRelease(letter);
}
}
}
CFRelease(line);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointZero];
[path appendPath:[UIBezierPath bezierPathWithCGPath:letters]];
CGPathRelease(letters);
CFRelease(font);
NSLog(#"==> %#",path);
// Creates layer
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame = drawingView.bounds;
pathLayer.bounds = CGPathGetBoundingBox(path.CGPath);
//pathLayer.backgroundColor = [[UIColor yellowColor] CGColor];
pathLayer.geometryFlipped = NO;
pathLayer.path = path.CGPath;
pathLayer.strokeColor = [[UIColor blackColor] CGColor];
pathLayer.fillColor = nil;
pathLayer.lineWidth = 3.0f;
pathLayer.lineJoin = kCALineJoinBevel;
[drawingView.layer addSublayer:pathLayer];
self.pathLayer = pathLayer;
// Add pointer
UIImage *penImage = [UIImage imageNamed:#"hand.png"];
CALayer *penLayer = [CALayer layer];
penLayer.contents = (id)penImage.CGImage;
penLayer.anchorPoint = CGPointMake(0.35f, 0.98f);
penLayer.frame = CGRectMake(0.0f, 0.0f, penImage.size.width, penImage.size.height);
[pathLayer addSublayer:penLayer];
self.penLayer = penLayer;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
pathAnimation.duration = 5.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.pathLayer addAnimation:pathAnimation forKey:#"strokeEnd"];
CAKeyframeAnimation *penAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
penAnimation.duration = 5.0;
penAnimation.path = self.pathLayer.path;
penAnimation.calculationMode = kCAAnimationPaced;
penAnimation.delegate = self;
[self.penLayer addAnimation:penAnimation forKey:#"position"];
This code draws latter latter in double line like the image below
instead i want to draw latter in single line like the image below
and the hand should draw the lines on centre of the font and not the border.

Apply gradient across multiple UITableViewCells

I have a UITableView with a white background, I would like to apply a linear gradient across the tableview cells so that the gradient is one single gradient from the start to end of the tableview see an example below from Adobe Illustrator. Is there a way this can be achieved using Core Graphics?
I actually managed to figure it out, to some extent from this question and help from matt
- (NSArray *)generateCellGradients
{
NSMutableArray *gradientColors = [[NSMutableArray alloc] init];
NSUInteger numberOfIntervals = self.datasource.count;
CGFloat startColorR = 81.0 / 255.0;
CGFloat startColorG = 118.0 / 255.0;
CGFloat startColorB = 214.0 / 255.0;
UIColor *startColor = [UIColor colorWithRed:startColorR
green:startColorG
blue:startColorB
alpha:1.0];
[gradientColors addObject:startColor];
CGFloat endColorR = 0;
CGFloat endColorG = 191.0 / 255.0;
CGFloat endColorB = 120.0 / 255.0;
UIColor *endColor = [UIColor colorWithRed:endColorR
green:endColorG
blue:endColorB
alpha:1.0];
CGFloat intervalR = (endColorR - startColorR) / numberOfIntervals;
CGFloat intervalG = (endColorG - startColorG) / numberOfIntervals;
CGFloat intervalB = (endColorB - startColorB) / numberOfIntervals;
for (NSUInteger i = 0; i < numberOfIntervals; i++) {
startColorR += intervalR;
startColorG += intervalG;
startColorB += intervalB;
UIColor *intervalColor = [UIColor colorWithRed:startColorR green:startColorG blue:startColorB alpha:1.0];
[gradientColors addObject:intervalColor];
}
[gradientColors addObject:endColor];
NSMutableArray *cellGradients = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < gradientColors.count; i++) {
UIColor *startGradientColor = gradientColors[i];
UIColor *endGradientColor;
if (i == gradientColors.count - 1) {
endGradientColor = gradientColors[i];
} else {
endGradientColor = gradientColors[i + 1];
}
NSArray *colors = #[(id)startGradientColor.CGColor, (id)endGradientColor.CGColor];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = colors;
[cellGradients addObject:gradientLayer];
}
return cellGradients;
}
This is how to add it to a subview:
CAGradientLayer *backgroundLayer = self.gradients[indexPath.row];
backgroundLayer.frame = view.bounds;
[view.layer insertSublayer:backgroundLayer atIndex:0];
Here is the result below:
Find below the code to create gradient layer by provide two required colours. You can add this layer to any view. Add this framework #import <QuartzCore/QuartzCore.h> in order to achieve this result.
typedef enum {
GradientType_Linear,
GradientType_Reflected,
}GradientType;
+(CAGradientLayer*) gradientLayerFromColor:(UIColor *)firstColor
secondColor:(UIColor *)secondColor
gradientType:(GradientType)gradientType
{
UIColor *colorStart = firstColor;
UIColor *colorEnd = secondColor;
NSArray *colors;
NSArray *locations;
switch (gradientType) {
case GradientType_Linear:
{
colors = [NSArray arrayWithObjects:(id)colorStart.CGColor, colorEnd.CGColor, nil];
NSNumber *start1 = [NSNumber numberWithFloat:0.0];
NSNumber *stop1 = [NSNumber numberWithFloat:1.0];
locations = [NSArray arrayWithObjects:start1, stop1, nil];
}
break;
case GradientType_Reflected:
{
colors = [NSArray arrayWithObjects:(id)colorStart.CGColor, colorEnd.CGColor, colorEnd.CGColor, colorStart.CGColor, nil];
NSNumber *start1 = [NSNumber numberWithFloat:0.0];
NSNumber *stop1 = [NSNumber numberWithFloat:0.5];
NSNumber *start2 = [NSNumber numberWithFloat:0.5];
NSNumber *stop2 = [NSNumber numberWithFloat:1.0];
locations = [NSArray arrayWithObjects:start1, stop1, start2, stop2, nil];
}
break;
default:
{
colors = [NSArray arrayWithObjects:(id)colorStart.CGColor, colorEnd.CGColor, nil];
NSNumber *start1 = [NSNumber numberWithFloat:0.0];
NSNumber *stop1 = [NSNumber numberWithFloat:1.0];
locations = [NSArray arrayWithObjects:start1, stop1, nil];
}
break;
}
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = colors;
gradientLayer.locations = locations;
return gradientLayer;
}

Core-Plot Select a point

I have successfully selected a point, but I hope at this point when selected, the point of color set to different from other points to distinguish,how to implement,Thanks a lot
How to set up only this one in red.
-(void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index{
CPTXYGraph graph = (CPTXYGraph)_graph;
if ( _symbolTextAnnotation ){
[graph.plotAreaFrame.plotArea removeAnnotation:_symbolTextAnnotation];
_symbolTextAnnotation = nil;
}
// Setup a style for the annotation
CPTMutableTextStyle *hitAnnotationTextStyle = [CPTMutableTextStyle textStyle];
hitAnnotationTextStyle.color = [CPTColor whiteColor];
hitAnnotationTextStyle.fontSize = 16.0;
hitAnnotationTextStyle.fontName = #"Helvetica-Bold";
// Determine point of symbol in plot coordinates
NSDictionary *dataPoint = _plotData[index];
NSNumber *x = dataPoint[#"x"];
NSNumber *y = dataPoint[#"y"];
NSArray *anchorPoint = #[x, y];
float yValue = [y floatValue];
NSString *yString = [NSString stringWithFormat:#"%.1f",yValue];
CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:yString style:hitAnnotationTextStyle];
CPTImage *background = [CPTImage imageWithCGImage:[UIImage imageNamed:#"bg_red"].CGImage];
textLayer.fill = [CPTFill fillWithImage:background];
textLayer.paddingLeft = 2.0;
textLayer.paddingTop = 2.0;
textLayer.paddingRight = 2.0;
textLayer.paddingBottom = 2.0;
self.symbolTextAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:graph.defaultPlotSpace anchorPlotPoint:anchorPoint];
_symbolTextAnnotation.contentLayer = textLayer;
_symbolTextAnnotation.contentAnchorPoint = CGPointMake(0.5, 0.0);
_symbolTextAnnotation.displacement = CGPointMake(0.0, 10.0);
[graph.plotAreaFrame.plotArea addAnnotation:_symbolTextAnnotation];
}
Implement the -symbolForScatterPlot:recordIndex: datasource method. Return nil to use the default plotSymbol, [NSNull null] to show no symbol, or a CPTPlotSymbol to show that symbol at the given data index.

EXC_BAD_ACCESS drawing graph

I'm drawing graph and for that I use SHLineGraphView now after drawing one graph I need to remove that and dray again. in line
CGPathMoveToPoint(backgroundPath, NULL, _leftMarginToLeave, plot.xPoints[0].y);
I am getting get EXC_BAD_ACCESS Message.
this is my function. I add NSZombieEnabled YES in my scheme
- (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];
UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 75, 75)];
circleLayer.path = circle.CGPath;
circleLayer.strokeColor = [UIColor orangeColor].CGColor;
circleLayer.fillColor = [UIColor whiteColor].CGColor;
circleLayer.shadowColor =[UIColor blackColor].CGColor;
circleLayer.lineWidth = 3.0;
[self.layer addSublayer:circleLayer];
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];
double yIntervalValue = yRange / INTERVAL_COUNT;
[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];
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);
}];
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 - 5, point.y - 5, 10, 10));
}
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;
CGPathRelease(backgroundPath);
CGPathRelease(circlePath);
CGPathRelease(graphPath);
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 - 10, point.y - 10, 40, 40);
[btn addTarget:self action:#selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
objc_setAssociatedObject(btn, kAssociatedPlotObject, plot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:btn];
}
}
Thanks

EXC_BAD_ACCESS in my code

Can be bad access from this part of code?
I'm trying to draw graph.And in my function i have BAD_ACCESS.I can't find what is wrong.
- (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];
UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 75, 75)];
circleLayer.path = circle.CGPath;
circleLayer.strokeColor = [UIColor orangeColor].CGColor;
circleLayer.fillColor = [UIColor whiteColor].CGColor;
circleLayer.shadowColor =[UIColor blackColor].CGColor;
circleLayer.lineWidth = 3.0;
[self.layer addSublayer:circleLayer];
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];
double yIntervalValue = yRange / INTERVAL_COUNT;
[plot.plottingValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *dic = (NSDictionary *)obj;
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
int xIndex = [self getIndexForValue:key forPlot:plot];
double height = self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE;
double y = height - ((height / ([_yAxisRange doubleValue] + yIntervalValue)) * [obj doubleValue]);
(plot.xPoints[xIndex]).x = ceil((plot.xPoints[xIndex]).x);
(plot.xPoints[xIndex]).y = ceil(y);
}];
}];
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 - 5, point.y - 5, 10, 10));
}
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;
CGPathRelease(backgroundPath);
CGPathRelease(circlePath);
CGPathRelease(graphPath);
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 - 10, point.y - 10, 40, 40);
[btn addTarget:self action:#selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
//objc_setAssociatedObject(btn, kAssociatedPlotObject, plot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:btn];
}
circleLayer = nil;
graphLayer = nil;
backgroundLayer = nil;
}
This is my full function I have bad access in line [self addSubview:btn];
Move your code into the enumerate block
[plot.plottingValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *dic = (NSDictionary *)obj;
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
int xIndex = [self getIndexForValue:key forPlot:plot];
double height = self.bounds.size.height - BOTTOM_MARGIN_TO_LEAVE;
double y = height - ((height / ([_yAxisRange doubleValue] + yIntervalValue)) * [obj doubleValue]);
(plot.xPoints[xIndex]).x = ceil((plot.xPoints[xIndex]).x);
(plot.xPoints[xIndex]).y = ceil(y);
}];
}];

Resources