iphone uilabel shadow emboss

iphone - iOS-¿Cómo lograr el efecto de relieve para el texto en UILabel?



shadow emboss (3)

¿Puedo saber cómo tener el efecto de relieve como el texto " Recordatorios " como se muestra en la imagen?

Parece que el texto está incrustado?

Gracias


ACTUALIZAR PARA iOS 7.0

En iOS 7.0, Apple agregó un nuevo atributo, NSTextEffectAttributeName , para cadenas atribuidas. Si su destino de despliegue es iOS 7.0 o posterior, puede establecer este atributo en NSTextEffectLetterpressStyle para dibujar una cadena atribuida en un estilo realzado.

ORIGINAL

No puedo decir con certeza cómo Apple dibuja el texto en relieve. Me parece que rellenan los glifos de cadena con un color rojizo, luego aplican una sombra alrededor de los bordes interiores de los glifos y también aplican una sombra muy tenue a lo largo de los bordes exteriores superiores de los glifos. Lo probé y así es como se ve:

En la parte superior está mi representación. Debajo hay un UILabel simple con la sombra como Chris sugirió en su respuesta. Puse una captura de pantalla de la aplicación Recordatorios en segundo plano.

Aquí está mi código.

Primero, necesitas una función que crea una máscara de imagen de tu cadena. Utilizará la máscara para dibujar la cuerda misma y luego dibujará una sombra que solo aparecerá alrededor de los bordes internos de la cuerda. Esta imagen solo tiene un canal alfa y no tiene canales RGB.

- (UIImage *)maskWithString:(NSString *)string font:(UIFont *)font size:(CGSize)size { CGRect rect = { CGPointZero, size }; CGFloat scale = [UIScreen mainScreen].scale; CGColorSpaceRef grayscale = CGColorSpaceCreateDeviceGray(); CGContextRef gc = CGBitmapContextCreate(NULL, size.width * scale, size.height * scale, 8, size.width * scale, grayscale, kCGImageAlphaOnly); CGContextScaleCTM(gc, scale, scale); CGColorSpaceRelease(grayscale); UIGraphicsPushContext(gc); { [[UIColor whiteColor] setFill]; [string drawInRect:rect withFont:font]; } UIGraphicsPopContext(); CGImageRef cgImage = CGBitmapContextCreateImage(gc); CGContextRelease(gc); UIImage *image = [UIImage imageWithCGImage:cgImage scale:scale orientation:UIImageOrientationDownMirrored]; CGImageRelease(cgImage); return image; }

Segundo, necesitas una función que invierta esa máscara. Lo usarás para hacer que CoreGraphics dibuje una sombra alrededor de los bordes interiores de la cadena. Esto debe ser una imagen RGBA completa. (iOS no parece ser compatible con imágenes de escala de grises + alfa).

- (UIImage *)invertedMaskWithMask:(UIImage *)mask { CGRect rect = { CGPointZero, mask.size }; UIGraphicsBeginImageContextWithOptions(rect.size, NO, mask.scale); { [[UIColor blackColor] setFill]; UIRectFill(rect); CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage); CGContextClearRect(UIGraphicsGetCurrentContext(), rect); } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }

Puede usarlos en una función que dibuja la cadena en rojo y aplica una sombra a sus bordes interiores.

-(UIImage *)imageWithInteriorShadowAndString:(NSString *)string font:(UIFont *)font textColor:(UIColor *)textColor size:(CGSize)size { CGRect rect = { CGPointZero, size }; UIImage *mask = [self maskWithString:string font:font size:rect.size]; UIImage *invertedMask = [self invertedMaskWithMask:mask]; UIImage *image; UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale); { CGContextRef gc = UIGraphicsGetCurrentContext(); // Clip to the mask that only allows drawing inside the string''s image. CGContextClipToMask(gc, rect, mask.CGImage); // We apply the mask twice because we''re going to draw through it twice. // Only applying it once would make the edges too sharp. CGContextClipToMask(gc, rect, mask.CGImage); mask = nil; // done with mask; let ARC free it // Draw the red text. [textColor setFill]; CGContextFillRect(gc, rect); // Draw the interior shadow. CGContextSetShadowWithColor(gc, CGSizeZero, 1.6, [UIColor colorWithWhite:.3 alpha:1].CGColor); [invertedMask drawAtPoint:CGPointZero]; invertedMask = nil; // done with invertedMask; let ARC free it image = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); return image; }

A continuación, necesita una función que toma una imagen y devuelve una copia con una leve sombra hacia arriba.

- (UIImage *)imageWithUpwardShadowAndImage:(UIImage *)image { UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); { CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, -1), 1, [UIColor colorWithWhite:0 alpha:.15].CGColor); [image drawAtPoint:CGPointZero]; } UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; }

Finalmente, puede combinar esas funciones para crear una imagen en relieve de su cadena. Puse mi imagen final en UIImageView para probarla fácilmente.

- (void)viewDidLoad { [super viewDidLoad]; CGRect rect = self.imageView.bounds; NSString *string = @"Reminders"; UIFont *font = [UIFont systemFontOfSize:33]; UIImage *interiorShadowImage = [self imageWithInteriorShadowAndString:string font:font textColor:[UIColor colorWithHue:0 saturation:.9 brightness:.7 alpha:1] size:rect.size]; UIImage *finalImage = [self imageWithUpwardShadowAndImage:interiorShadowImage]; self.imageView.image = finalImage; }


Eso solo parece una sombra alrededor del texto. Lo configura en IB en la misma área donde configura el color del texto: seleccione un color apropiado para la sombra y configure cómo desea que se desplace la sombra (en el ejemplo que publicó, parece que configuraron el color de la sombra del mismo color como el texto y compensarlo 0 horizontal y -1 vertical (lo que significa un píxel arriba).

En el código, las propiedades se establecen de esta manera (suponiendo que ya ha configurado un nombre UILabel, apropiadamente, "etiqueta":

label.shadowColor = [UIColor blackColor]; // Choose your color here - in the example // posted, they probably chose a similar color // to the text color and then set the alpha // down around 0.7 or so so the shadow would be // faint. label.shadowOffset = CGSizeMake(0,-1); // First parameter is horizontal, second is vertical


Puede configurar su efecto sobre la base de este ejemplo