2011-06-04 6 views
8

Tengo un problema con las sombras de CALayer. Así es como estoy haciendo mi punto de vista:Añadir sombra a la capa provoca una apariencia de retina degradada

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

Bien, entonces eso funciona bien. La imagen agregada es la resolución retina. Sin embargo, tan pronto como agrego una sombra a la capa, salta a la resolución estándar, haciendo que el botón parezca borroso.

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; 

¿Hay alguna razón por la que agregar una sombra podría causar este problema?

Respuesta

20

Realmente no puedo decir, por qué sucede, pero supongo que es causado por la creación de UIImage. Creó un CGImageRef grande (retina tamaño 600 * 600 píxeles) y de ahí el UIImage. Pero el UIImage no es consciente, es una imagen de retina (ahora tiene 600 * 600 puntos, debería tener 300 * 300 puntos con un factor de escala 2 que nuevamente dará como resultado 600 * 600 píxeles).

Intente crear su UIImage usando imageWithCGImage:scale:orientation:. Esto hará que el UIImage esté al tanto de la escala de retina y las operaciones de capa pueden funcionar bien.

Así que su línea sería:

UIImage *img1 = [UIImage imageWithCGImage:ref1 
    scale: scale 
    orientation: UIImageOrientationUp]; 

Editar (ver mi comentario a continuación): El problema está causado por l1.layer.shouldRasterize = YES. También debe especificar l1.layer.rasterizationScale = scale y la imagen se visualiza como se espera.

+0

Gracias por su sugerencia, pero parece que no funciona. Aún vuelve a la resolución estándar. :/ –

+12

Lo probé yo mismo. La causa es que la representación incorrecta es l1.layer.shouldRasterize = YES; Necesita establecer l1.layer.rasterizationScale = scale también. – marcus

+0

Ese fue el problema. ¡Gracias por ayudar! –

Cuestiones relacionadas