Ich möchte nur einen schwarzen Rand von einem Pixel um meinen weißen UILabel-Text.
Ich bin so weit gekommen, UILabel mit dem folgenden Code zu unterklassifizieren, den ich aus einigen tangential verwandten Online-Beispielen ungeschickt zusammengeschustert habe. Und es funktioniert, aber es ist sehr, sehr langsam (außer im Simulator) und ich konnte es auch nicht dazu bringen, den Text vertikal zu zentrieren (also habe ich den y-Wert in der letzten Zeile vorübergehend fest codiert). 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]);
}
Ich habe nur das quälende Gefühl, dass ich einen einfacheren Weg übersehe, dies zu tun. Vielleicht durch Überschreiben von "drawTextInRect", aber ich kann drawTextInRect anscheinend nicht dazu bringen, sich meinem Willen zu beugen, obwohl ich es aufmerksam anstarrte und wirklich sehr, sehr hart die Stirn runzelte.
quelle
Antworten:
Ich konnte dies tun, indem ich drawTextInRect überschrieb:
quelle
UILabel
die-drawTextInRect:
Implementierung unterordnen und dort platzieren.Eine einfachere Lösung besteht darin, einen Attributed String wie folgt zu verwenden :
Swift 4:
Swift 4.2:
Auf einem können
UITextField
Sie dasdefaultTextAttributes
und dasattributedPlaceholder
auch einstellen .Beachten Sie, dass in diesem Fall
NSStrokeWidthAttributeName
das negativ sein muss, dh nur die inneren Umrisse funktionieren.quelle
Nachdem ich die akzeptierte Antwort und die beiden Korrekturen sowie die Antwort von Axel Guilmin gelesen hatte, beschloss ich, in Swift eine Gesamtlösung zu erstellen, die zu mir passt:
Sie können diese benutzerdefinierte UILabel-Klasse zu einer vorhandenen Beschriftung im Interface Builder hinzufügen und die Dicke des Rahmens und seine Farbe ändern, indem Sie benutzerdefinierte Laufzeitattribute wie folgt hinzufügen:
Ergebnis:
quelle
Es gibt ein Problem bei der Implementierung der Antwort. Das Zeichnen eines Textes mit Strich hat eine etwas andere Zeichenzeichenbreite als das Zeichnen eines Textes ohne Strich, was zu "nicht zentrierten" Ergebnissen führen kann. Sie kann durch Hinzufügen eines unsichtbaren Strichs um den Fülltext behoben werden.
Ersetzen:
mit:
Ich bin mir nicht 100% sicher, ob das der wahre Deal ist, weil ich nicht weiß, ob
self.textColor = textColor;
es den gleichen Effekt hat wie[textColor setFill]
, aber es sollte funktionieren.Offenlegung: Ich bin der Entwickler von THLabel.
Ich habe vor einiger Zeit eine UILabel-Unterklasse veröffentlicht, die eine Gliederung in Text und anderen Effekten ermöglicht. Sie finden es hier: https://github.com/tobihagemann/THLabel
quelle
Dadurch wird an sich kein Umriss erstellt, aber es wird ein Schatten um den Text gelegt. Wenn Sie den Schattenradius so klein machen, dass er einem Umriss ähnelt.
Ich weiß nicht, ob es mit älteren Versionen von iOS kompatibel ist.
Wie auch immer, ich hoffe es hilft ...
quelle
Eine Swift 4-Klassenversion basierend auf der Antwort von kprevas
Es kann vollständig im Interface Builder implementiert werden, indem die benutzerdefinierte Klasse des UILabels auf OutlinedText gesetzt wird. Anschließend können Sie die Breite und Farbe der Kontur im Eigenschaftenbereich festlegen.
quelle
Wenn Sie etwas Kompliziertes animieren möchten, ist es am besten, programmgesteuert einen Screenshot davon zu erstellen und stattdessen zu animieren!
Um einen Screenshot einer Ansicht zu erstellen, benötigen Sie einen Code wie den folgenden:
Wobei mainContentView die Ansicht ist, von der Sie einen Screenshot machen möchten. Fügen Sie viewImage zu einer UIImageView hinzu und animieren Sie diese.
Hoffe das beschleunigt deine Animation !!
N.
quelle
Als MuscleRumble erwähnte, liegt der Rand der akzeptierten Antwort etwas außerhalb der Mitte. Ich konnte dies korrigieren, indem ich die Strichbreite auf Null setzte, anstatt die Farbe auf Klar zu ändern.
dh ersetzen:
mit:
Ich hätte seine Antwort nur kommentiert, aber anscheinend bin ich nicht "seriös" genug.
quelle
Wenn alles, was Sie wollen, ein schwarzer Rand mit einem Pixel um meinen weißen UILabel-Text ist,
dann denke ich, dass Sie das Problem schwieriger machen als es ist ... Ich weiß nicht aus dem Speicher, welche Funktion 'draw rect / frameRect' Sie verwenden sollten, aber es wird für Sie leicht zu finden sein. Diese Methode demonstriert nur die Strategie (lassen Sie die Superklasse die Arbeit machen!):
quelle
Ich habe ein Problem mit der Hauptantwort gefunden. Die Textposition ist nicht unbedingt korrekt auf die Subpixelposition zentriert, sodass der Umriss um den Text herum nicht übereinstimmen kann. Ich habe es mit dem folgenden Code behoben, der verwendet
CGContextSetShouldSubpixelQuantizeFonts(ctx, false)
:Dies setzt voraus, dass Sie
textOutlineColor
undtextOutlineWidth
als Eigenschaften definiert haben .quelle
Hier ist die andere Antwort, um den umrissenen Text auf dem Etikett festzulegen.
Stellen Sie den umrissenen Text einfach mit der Erweiterungsmethode ein.
quelle
Es ist auch möglich, UILabel mit der folgenden Logik zu unterordnen:
und wenn Sie Text in Storyboard festlegen, dann:
quelle
Wenn Ihr Ziel so etwas ist:
So habe ich es erreicht: Ich
label
habe meinem aktuellen UILabel eine neue benutzerdefinierte Klasse als Unteransicht hinzugefügt (inspiriert von dieser Antwort) ).Kopieren Sie es einfach und fügen Sie es in Ihr Projekt ein.
VERWENDUNG:
es funktioniert auch für a
UIButton
mit all seinen animationen:quelle
Warum erstellen Sie in Photoshop keine 1px-Rahmen-UIView, legen dann eine UIView mit dem Bild fest und positionieren es hinter Ihrem UILabel?
Code:
Es wird Ihnen die Unterklasse eines Objekts ersparen und es ist ziemlich einfach zu tun.
Ganz zu schweigen davon, ob Sie Animationen erstellen möchten, diese sind in die UIView-Klasse integriert.
quelle
Um einen Rand mit abgerundeten Kanten um ein UILabel zu legen, gehe ich wie folgt vor:
(Vergessen Sie nicht, QuartzCore / QuartzCore.h einzuschließen.)
quelle