Adding shadow to layer causes degraded retina appearance
I've got a problem with CALayer shadows. Here's how I'm making my view:
UIImage *screenshot = [SomeClass getScreenshot:mainView.view]; //full screen snap
CGFloat scale = [SomeClass getScreenScale]; // 1 or 2 for retina
CGFloat width = mainView.view.frame.size.width;
CGRect r1 = CGRectMake(0, 0, width*scale, 300*scale);
CGRect u1 = CGRectMake(0, 0, width, 300);
CGImageRef ref1 = CGImageCreateWithImageInRect([screenshot CGImage], r1)开发者_开发知识库;
l1 = [[UIButton alloc] initWithFrame:u1];
UIImage *img1 = [UIImage imageWithCGImage:ref1];
[l1 setBackgroundImage:img1 forState:UIControlStateNormal];
[l1 setAdjustsImageWhenHighlighted:NO];
CGImageRelease(ref1);
[mainView.view addSubview:l1];
Okay, so that works just fine. The image added is retina resolution. However, as soon as I add a shadow to the layer it jumps to standard resolution, making the button appear fuzzy.
l1.layer.shadowOffset = CGSizeMake(0, 0);
l1.layer.shadowRadius = 20;
l1.layer.shadowColor = [UIColor blackColor].CGColor;
l1.layer.shadowOpacity = 0.8f;
l1.layer.shouldRasterize = YES;
Is there any reason why adding a shadow would cause this problem?
I cannot really tell, why it happens, but I assume it is caused by the UIImage creation. You created a large(retina size 600 * 600 pixels) CGImageRef and from that the UIImage. But the UIImage is not aware, that it is a retina image (it now has 600 * 600 points, it should have 300 * 300 points with scale factor 2 which again will result in 600 * 600 pixels).
Please try to create your UIImage
using imageWithCGImage:scale:orientation:
. This will make the UIImage aware of retina-scale and the layer operations may work out ok.
So your line would be:
UIImage *img1 = [UIImage imageWithCGImage:ref1
scale: scale
orientation: UIImageOrientationUp];
Edit (see my comment below): The issue is caused by l1.layer.shouldRasterize = YES
. You need to specify l1.layer.rasterizationScale = scale
as well and the image renders as expected.
精彩评论