Todo lo que quiero es un borde negro de un píxel alrededor de mi texto UILabel blanco.
Llegué a subclasificar UILabel con el siguiente código, que improvisé torpemente a partir de algunos ejemplos en línea relacionados tangencialmente. Y funciona, pero es muy, muy lento (excepto en el simulador) y tampoco pude conseguir que centre el texto verticalmente (así que codifiqué temporalmente el valor y en la última línea). ¡Ahhhh!
void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {
CGContextSetTextDrawingMode(gc, kCGTextInvisible);
CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));
CGPoint pt = CGContextGetTextPosition(gc);
CGContextSetTextDrawingMode(gc, kCGTextFillStroke);
CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str));
}
- (void)drawRect:(CGRect)rect{
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGRect viewBounds = self.bounds;
CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
CGContextScaleCTM(theContext, 1, -1);
CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height, kCGEncodingMacRoman);
CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);
CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);
CGContextSetLineWidth(theContext, 1.0);
ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]);
}
Solo tengo la persistente sensación de que estoy pasando por alto una forma más sencilla de hacer esto. Quizás anulando "drawTextInRect", pero parece que no puedo conseguir que drawTextInRect se doble a mi voluntad a pesar de mirarlo fijamente y fruncir el ceño muy, muy duro.
ios
objective-c
iphone
cocoa-touch
core-graphics
Monte Hurd
fuente
fuente
Respuestas:
Pude hacerlo anulando drawTextInRect:
fuente
UILabel
crear una subclase y poner la-drawTextInRect:
implementación allí.Una solución más simple es usar una cadena de atributos como esta:
Rápido 4:
Rápido 4.2:
En a,
UITextField
también puede configurar eldefaultTextAttributes
y elattributedPlaceholder
.Tenga en cuenta que
NSStrokeWidthAttributeName
tiene que ser negativo en este caso, es decir, solo funcionan los contornos internos.fuente
Después de leer la respuesta aceptada y las dos correcciones y la respuesta de Axel Guilmin, decidí compilar una solución general en Swift, que me conviene:
Puede agregar esta clase UILabel personalizada a una etiqueta existente en Interface Builder y cambiar el grosor del borde y su color agregando Atributos de tiempo de ejecución definidos por el usuario como este:
Resultado:
fuente
Hay un problema con la implementación de la respuesta. Dibujar un texto con trazo tiene un ancho de glifo de carácter ligeramente diferente al dibujo de un texto sin trazo, lo que puede producir resultados "no centrados". Se puede solucionar agregando un trazo invisible alrededor del texto de relleno.
Reemplazar:
con:
No estoy 100% seguro, si ese es el verdadero negocio, porque no sé si
self.textColor = textColor;
tiene el mismo efecto[textColor setFill]
, pero debería funcionar.Divulgación: soy el desarrollador de THLabel.
Lancé una subclase de UILabel hace un tiempo, que permite un esquema en el texto y otros efectos. Puede encontrarlo aquí: https://github.com/tobihagemann/THLabel
fuente
Esto no creará un contorno per se, pero pondrá una sombra alrededor del texto, y si hace que el radio de la sombra sea lo suficientemente pequeño, podría parecerse a un contorno.
No sé si es compatible con versiones anteriores de iOS.
De todos modos, espero que ayude ...
fuente
Una versión de clase Swift 4 basada en la respuesta de kprevas
Se puede implementar completamente en Interface Builder configurando la clase personalizada de UILabel en OutlinedText. A continuación, tendrá la capacidad de establecer el ancho y el color del contorno desde el panel Propiedades.
fuente
Si desea animar algo complicado, la mejor manera es tomar una captura de pantalla programáticamente y animarlo en su lugar.
Para tomar una captura de pantalla de una vista, necesitará un código como este:
Donde mainContentView es la vista de la que desea tomar una captura de pantalla. Agregue viewImage a un UIImageView y anímelo.
¡Espero que acelere tu animación!
norte
fuente
Como mencionó MuscleRumble , el borde de la respuesta aceptada está un poco descentrado. Pude corregir esto estableciendo el ancho del trazo en cero en lugar de cambiar el color a claro.
es decir, reemplazando:
con:
Solo habría comentado su respuesta, pero aparentemente no soy lo suficientemente "respetable".
fuente
si TODO lo que quieres es un borde negro de un píxel alrededor de mi texto UILabel blanco,
entonces creo que está haciendo el problema más difícil de lo que es ... No sé por memoria qué función 'dibujar rect / frameRect' debería usar, pero será fácil de encontrar. este método simplemente demuestra la estrategia (¡deje que la superclase haga el trabajo!):
fuente
Encontré un problema con la respuesta principal. La posición del texto no está necesariamente centrada correctamente en la ubicación de los subpíxeles, por lo que el contorno puede no coincidir con el texto. Lo arreglé usando el siguiente código, que usa
CGContextSetShouldSubpixelQuantizeFonts(ctx, false)
:Esto supone que definiste
textOutlineColor
ytextOutlineWidth
como propiedades.fuente
Aquí está la otra respuesta para establecer el texto delineado en la etiqueta.
establecer texto delineado simplemente usando el método de extensión.
fuente
También es posible subclasificar UILabel con la siguiente lógica:
y si establece texto en Storyboard, entonces:
fuente
Si tu objetivo es algo como esto:
Así es como lo logré: agregué una nueva
label
clase personalizada como una Subvista a mi UILabel actual (inspirada en esta respuesta ).Simplemente cópielo y péguelo en su proyecto y estará listo:
USO:
también funciona para a
UIButton
con todas sus animaciones:fuente
¿Por qué no crea una UIView de borde de 1px en Photoshop, luego establece una UIView con la imagen y la coloca detrás de su UILabel?
Código:
Te ahorrará subclasificar un objeto y es bastante simple de hacer.
Sin mencionar si desea hacer animación, está integrado en la clase UIView.
fuente
Para poner un borde con bordes redondeados alrededor de un UILabel, hago lo siguiente:
(no olvide incluir QuartzCore / QuartzCore.h)
fuente