Reputation: 3149
I have a CAShapeLayer that I'm using to draw tiny dots in a bar chart. The problem is that they are all too big on the retina displays. I have set the contentsScale and checked that it is getting set. Still I see no difference with it or without it!
CAShapeLayer *lineShapeLayer = [CAShapeLayer layer];
lineShapeLayer.contentsScale = [[UIScreen mainScreen] scale];
CGMutablePathRef path = CGPathCreateMutable();
lineShapeLayer.backgroundColor = [UIColor clearColor].CGColor;
lineShapeLayer.bounds = CGRectMake(0, 0, self.backgroundLayer.bounds.size.width, 1.5);
lineShapeLayer.anchorPoint = CGPointMake(0, 0);
lineShapeLayer.position = CGPointMake(0, rint((self.verticalPartitionHeight)*i));
lineShapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:1], [NSNumber numberWithInt:2], nil];
lineShapeLayer.strokeColor = [UIColor blackColor].CGColor;
lineShapeLayer.lineWidth = 1;
NSLog(@"contentsScale: %f", lineShapeLayer.contentsScale);
CGPathMoveToPoint(path, nil, 0, .5);
CGPathAddLineToPoint(path, nil, lineShapeLayer.frame.size.width, .5);
[lineShapeLayer setPath:path];
[self.backgroundLayer addSublayer:lineShapeLayer];
Here is the view if I make it with PNGs:
Here is the view with the CAShapeLayer code (set to line width .5 even.):
Upvotes: 2
Views: 1856
Reputation: 1
Best way to scale CAShapeLayer
is the following:
CAShapeLayer *pathLayer = [CAShapeLayer layer];
[pathLayer setTransform:CATransform3DMakeScale(0.1, 0.1, 0.1)];
Upvotes: 0
Reputation: 3149
@David Ronnqvist was right! The contentsScale was working. I just had to make the line width even smaller and then put the whole thing on the .25 (which is .5/2)!
CAShapeLayer *lineShapeLayer = [CAShapeLayer layer];
lineShapeLayer.contentsScale=[[UIScreen mainScreen] scale];
CGMutablePathRef path = CGPathCreateMutable();
lineShapeLayer.backgroundColor=[UIColor clearColor].CGColor;
lineShapeLayer.bounds=CGRectMake(0, 0, self.backgroundLayer.bounds.size.width, 0.5);
lineShapeLayer.anchorPoint=P(0,0);
lineShapeLayer.position=P(0,rint((self.verticalPartitionHeight)*i));
lineShapeLayer.lineDashPattern=[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.5], [NSNumber numberWithInt:1], nil];
lineShapeLayer.strokeColor=[UIColor grayColor].CGColor;
lineShapeLayer.lineWidth=0.5;
lineShapeLayer.shadowColor=[UIColor whiteColor].CGColor;
lineShapeLayer.shadowOffset=CGSizeMake(0, 0.5);
lineShapeLayer.shadowOpacity=1.0;
lineShapeLayer.shadowRadius=0;
NSLog(@"lineShapeLayer.frame: %@", NSStringFromCGRect(lineShapeLayer.frame));
CGPathMoveToPoint(path, nil, 0, 0.25);
CGPathAddLineToPoint(path, nil, lineShapeLayer.frame.size.width, 0.25);
[lineShapeLayer setPath:path];
Of course I'll make this not hardcoded for scale but divisible by the scale.
Upvotes: 0
Reputation: 56635
There is nothing wrong with you code unless its somewhere else. I ran the code above inside a loop (I'm assuming i
is the index) with self.verticalPartitionHeight = 30.0
.
The two images below are the result in both normal resolution and retina resolution. I've scaled up the normal image to make them the same size. The dots are, as you can see, the same size (in points, not pixels) on both resolutions.
You mention that the Stocks app does this in Landscape but if you zoom in on a screenshot of it you will actually see that it actually uses points (since every dot is 2x2 pixels). You can see this in the screenshot below (from a retina screenshot) where I zoomed in a lot on the dots and selected one pixel of one dot.
This is the expected behavior.
One more zoomed up look at your dots. They are actually the exact same size as the dots in Apples Stocks app. You can see it in the image below where I have selected one pixel.
Upvotes: 4