Tout ce que je veux, c'est une bordure noire d'un pixel autour de mon texte UILabel blanc.
Je suis allé jusqu'à sous-classer UILabel avec le code ci-dessous, que j'ai maladroitement bricolé à partir de quelques exemples en ligne liés de manière tangentielle. Et cela fonctionne mais c'est très, très lent (sauf sur le simulateur) et je n'ai pas pu le faire centrer le texte verticalement non plus (j'ai donc codé en dur la valeur y sur la dernière ligne temporairement). 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]);
}
J'ai juste le sentiment tenace que j'oublie une façon plus simple de faire cela. Peut-être en écrasant "drawTextInRect", mais je n'arrive pas à faire en sorte que drawTextInRect se plie à ma volonté malgré le fait de le regarder attentivement et de froncer les sourcils vraiment très fort.
la source
Réponses:
J'ai pu le faire en remplaçant drawTextInRect:
la source
UILabel
et y mettre l'-drawTextInRect:
implémentation.Une solution plus simple consiste à utiliser une chaîne attribuée comme ceci:
Swift 4:
Swift 4.2:
Sur a,
UITextField
vous pouvez également définir ledefaultTextAttributes
et leattributedPlaceholder
.Notez que le
NSStrokeWidthAttributeName
doit être négatif dans ce cas, c'est-à-dire que seuls les contours intérieurs fonctionnent.la source
Après avoir lu la réponse acceptée et les deux corrections qui y sont apportées et la réponse d'Axel Guilmin, j'ai décidé de compiler une solution globale en Swift, qui me convient:
Vous pouvez ajouter cette classe UILabel personnalisée à une étiquette existante dans l'Interface Builder et modifier l'épaisseur de la bordure et sa couleur en ajoutant des attributs d'exécution définis par l'utilisateur comme ceci:
Résultat:
la source
Il y a un problème avec la mise en œuvre de la réponse. Le dessin d'un texte avec un contour a une largeur de glyphe de caractère légèrement différente de celle d'un texte sans contour, ce qui peut produire des résultats «non centrés». Il peut être corrigé en ajoutant un trait invisible autour du texte de remplissage.
Remplacer:
avec:
Je ne suis pas sûr à 100% si c'est la vraie affaire, car je ne sais pas si cela
self.textColor = textColor;
a le même effet que[textColor setFill]
, mais cela devrait fonctionner.Divulgation: je suis le développeur de THLabel.
J'ai publié une sous-classe UILabel il y a quelque temps, qui permet un contour dans le texte et d'autres effets. Vous pouvez le trouver ici: https://github.com/tobihagemann/THLabel
la source
Cela ne créera pas de contour en soi, mais cela mettra une ombre autour du texte, et si vous réduisez suffisamment le rayon de l'ombre, cela pourrait ressembler à un contour.
Je ne sais pas s'il est compatible avec les anciennes versions d'iOS.
Quoi qu'il en soit, j'espère que cela aide ...
la source
Une version de classe Swift 4 basée sur la réponse de kprevas
Il peut être entièrement implémenté dans Interface Builder en définissant la classe personnalisée de UILabel sur OutlinedText. Vous aurez alors la possibilité de définir la largeur et la couleur du contour à partir du volet Propriétés.
la source
Si vous voulez animer quelque chose de compliqué, le meilleur moyen est de prendre une capture d'écran par programme et de l'animer à la place!
Pour prendre une capture d'écran d'une vue, vous aurez besoin d'un code un peu comme celui-ci:
Où mainContentView est la vue dont vous souhaitez prendre une capture d'écran. Ajoutez viewImage à un UIImageView et animez-le.
J'espère que cela accélère votre animation !!
N
la source
Comme MuscleRumble l'a mentionné, la frontière de la réponse acceptée est un peu décentrée. J'ai pu corriger cela en définissant la largeur du trait sur zéro au lieu de changer la couleur pour effacer.
c'est-à-dire en remplaçant:
avec:
J'aurais juste commenté sa réponse mais apparemment je ne suis pas assez "réputé".
la source
si TOUT ce que vous voulez est une bordure noire d'un pixel autour de mon texte UILabel blanc,
alors je pense que vous rendez le problème plus difficile qu'il ne l'est ... Je ne sais pas par mémoire quelle fonction 'draw rect / frameRect' vous devriez utiliser, mais il vous sera facile de la trouver. cette méthode démontre simplement la stratégie (laissez la superclasse faire le travail!):
la source
J'ai trouvé un problème avec la réponse principale. La position du texte n'est pas nécessairement centrée correctement sur l'emplacement du sous-pixel, de sorte que le contour peut être incohérent autour du texte. Je l'ai corrigé en utilisant le code suivant, qui utilise
CGContextSetShouldSubpixelQuantizeFonts(ctx, false)
:Cela suppose que vous avez défini
textOutlineColor
ettextOutlineWidth
comme propriétés.la source
Voici une autre réponse pour définir le texte souligné sur l'étiquette.
définir le texte encadré simplement en utilisant la méthode d'extension.
la source
il est également possible de sous-classer UILabel avec la logique suivante:
et si vous définissez du texte dans Storyboard, alors:
la source
Si votre objectif est quelque chose comme ceci:
Voici comment je l'ai réalisé: j'ai ajouté une nouvelle
label
classe personnalisée en tant que sous-vue à mon UILabel actuel (inspiré par cette réponse ).Copiez-collez-le simplement dans votre projet et vous êtes prêt à partir:
USAGE:
ça marche aussi pour un
UIButton
avec toutes ses animations:la source
Pourquoi ne pas créer une UIView de bordure 1px dans Photoshop, puis définir une UIView avec l'image et la positionner derrière votre UILabel?
Code:
Cela vous évitera de sous-classer un objet et c'est assez simple à faire.
Sans oublier si vous voulez faire de l'animation, elle est intégrée à la classe UIView.
la source
Pour mettre une bordure avec des bords arrondis autour d'un UILabel, je fais ce qui suit:
(n'oubliez pas d'inclure QuartzCore / QuartzCore.h)
la source