How to set custom tick marks in Core Plot to icons

2019-04-14 23:33发布

Is there a way to make tick mark (major tick mark) to be UIImage (custom graphics) instead of text? I have values in one of the axis I need to present as icons. I do not see any delegate for this but maybe someone knows the trick?

2条回答
聊天终结者
2楼-- · 2019-04-14 23:57

Axis labels can have any CPTLayer (which is a direct subclass of Core Animation's CALayer) as its content. Set your image as the layer background and build a custom label using this layer. Several of the Core Plot example apps demonstrate custom labels, although they all use text labels.

You have two options for adding your custom labels to the graph:

  1. Use the CPTAxisLabelingPolicyNone labeling policy. Create a NSSet containing your labels and set it to the axisLabels property on the axis. If you use this, remember that you must provide the major and/or minor tick locations in addition to the custom labels.

  2. Use any other labeling policy to generate the tick locations and implement the -axis:shouldUpdateAxisLabelsAtLocations: axis delegate method. In your delegate, create new labels at the provided locations and return NO to suppress the automatic labels.

Eric

查看更多
ゆ 、 Hurt°
3楼-- · 2019-04-15 00:04

Accepting Eric's question and thanking him I provide working code for his suggested solution. Maybe it helps someone:

if (yAxisIcons) {


    int custonLabelsCount = [self.yAxisIcons count];

    NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:custonLabelsCount];

    for (NSUInteger i = 0; i < custonLabelsCount; i++) {

        NSNumber *tickLocation = [NSNumber numberWithInt:i];
        NSString *file = [yAxisIcons objectAtIndex:i];
        UIImage *icon = [UIImage imageNamed:file];

        CPImageLayer *layer; // My custom CPLayer subclass - see code below

          CGFloat nativeHeight = 1;
          CGFloat nativeWidth = 1;


        if (icon) {

            layer = [[CPImageLayer alloc] initWithImage:icon];
            nativeWidth = 20;//CGImageGetWidth(icon.CGImage);
            nativeHeight = 20;//CGImageGetHeight(icon.CGImage);
            //layer.contents = (id)icon.CGImage;

            if (nativeWidth > biggestCustomIconWidth) {
                biggestCustomIconWidth = nativeWidth;
            }

        }else{
            layer = [[CPImageLayer alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
        }

            CGRect  startFrame = CGRectMake(0.0, 0.0, nativeWidth, nativeHeight);

            layer.frame = startFrame;
            layer.backgroundColor = [UIColor clearColor].CGColor;
            CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithContentLayer:layer];
            newLabel.tickLocation = [tickLocation decimalValue];
            newLabel.offset = x.labelOffset + x.majorTickLength;
            [customLabels addObject:newLabel];
            [newLabel release];
            [layer release];

    }

    y.axisLabels =  [NSSet setWithArray:customLabels];

}

CPImageLayer.h

#import "CPLayer.h"

@interface CPImageLayer : CPLayer {

    UIImage *_image;

}
-(id)initWithImage:(UIImage *)image;
@end

CPImageLayer.m

#import "CPImageLayer.h"
#import "CPLayer.h"

@implementation CPImageLayer

-(void)dealloc{

    [_image release];
    [super dealloc];
}
-(id)initWithImage:(UIImage *)image{

    CGRect f = CGRectMake(0, 0, image.size.width, image.size.height);

    if (self = [super initWithFrame:f]) {

        _image = [image retain];
    }

    return self;

}

-(void)drawInContext:(CGContextRef)ctx{

    CGContextDrawImage(ctx, self.bounds, _image.CGImage);

}
@end

Enjoy

查看更多
登录 后发表回答