Ich habe eine Stelle, UILabel
an der ich oben und unten Platz hinzufügen möchte. Mit minimaler Höhe in Einschränkung habe ich es geändert zu:
EDIT: Um dies zu tun, habe ich verwendet:
override func drawTextInRect(rect: CGRect) {
var insets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
Aber ich muss eine andere Methode finden, denn wenn ich mehr als zwei Zeilen schreibe, ist das Problem dasselbe:
Antworten:
Wenn Sie bei UILabel bleiben möchten, ohne es zu unterordnen, hat Mundi Ihnen eine klare Lösung gegeben.
Wenn Sie alternativ vermeiden möchten, das UILabel mit einem UIView zu umschließen, können Sie UITextView verwenden, um die Verwendung von UIEdgeInsets (Auffüllen) zu aktivieren, oder UILabel der Unterklasse, um UIEdgeInsets zu unterstützen.
Bei Verwendung einer UITextView müssten nur die Einfügungen (OBJ-C) bereitgestellt werden :
Alternativ, wenn Sie UILabel unterordnen , würde ein Beispiel für diesen Ansatz die drawTextInRect- Methode
(OBJ-C) überschreiben.
Sie können Ihrem neuen UILabel der Unterklasse zusätzlich Einfügungsvariablen für TOP, LEFT, BOTTOM und RIGHT bereitstellen.
Ein Beispielcode könnte sein:
In .h (OBJ-C)
In .m (OBJ-C)
EDIT # 1:
Nach allem, was ich gesehen habe, müssen Sie die intrinsicContentSize des UILabels überschreiben, wenn Sie es in Unterklassen unterteilen.
Sie sollten intrinsicContentSize also wie folgt überschreiben :
Fügen Sie die folgende Methode hinzu, um Ihre Insets zu bearbeiten, anstatt sie einzeln zu bearbeiten:
Die Größe Ihres UILabel wird aktualisiert, um den Kanteneinsätzen zu entsprechen und die von Ihnen erwähnte mehrzeilige Notwendigkeit abzudecken.
Bearbeiten Sie # 2
Nach einigem Suchen habe ich diesen Gist mit einem IPInsetLabel gefunden. Wenn keine dieser Lösungen funktioniert, können Sie sie ausprobieren.
Bearbeiten Sie # 3
Es gab eine ähnliche Frage (Duplikat) zu dieser Angelegenheit.
Eine vollständige Liste der verfügbaren Lösungen finden Sie in dieser Antwort: UILabel-Textrand
quelle
Ich habe es auf Swift 4.2 versucht , hoffentlich funktioniert es für Sie!
Oder Sie können CocoaPods hier verwenden https://github.com/levantAJ/PaddingLabel
pod 'PaddingLabel', '1.2'
quelle
min
Swift 3
quelle
Sie können es richtig von IB machen:
quelle
SWIFT 4
Einfach zu bedienende Lösung, verfügbar für alle UILabel-Kinder im Projekt.
Beispiel:
UILabel-Erweiterung
quelle
Verwenden Sie einfach a
UIView
als Übersicht und definieren Sie einen festen Rand für das Etikett mit automatischem Layout.quelle
drawTextInRect
funktioniert nur für 1 Zeile,intrinsicContentSize
funktioniert nicht mit horizontaler Polsterung. UILabel in UIView einwickeln ist der gute WegVerwenden Sie einfach einen UIButton, der bereits integriert ist. Deaktivieren Sie alle zusätzlichen Schaltflächenfunktionen und Sie haben eine Beschriftung, auf der Sie Kanteninstets festlegen können.
quelle
isUserInteractionEnabled = false
ist praktisch, um sie zu deaktivieren.Ohne Storyboard:
Verwendung:
Ergebnis:
quelle
Polsterung einer
UILabel
vollständigen Lösung. Aktualisiert für 2020.Es stellt sich heraus, dass drei Dinge getan werden müssen.
1. Muss textRect # forBounds mit der neuen kleineren Größe aufrufen
2. Muss drawText mit der neuen kleineren Größe überschreiben
3. Wenn es sich um eine Zelle mit dynamischer Größe handelt, muss intrinsicContentSize angepasst werden
Im folgenden typischen Beispiel befindet sich die Texteinheit in einer Tabellenansicht, Stapelansicht oder einer ähnlichen Konstruktion, wodurch sie eine feste Breite erhält . Im Beispiel wollen wir eine Polsterung von 60,20,20,24.
Daher nehmen wir die "vorhandene" intrinsicContentSize und addieren tatsächlich 80 zur Höhe .
Wiederholen ...
Ich finde diesen Prozess verwirrend, aber so funktioniert es. Für mich sollte Apple einen Anruf mit dem Namen "vorläufige Höhenberechnung" veröffentlichen.
Zweitens müssen wir den Aufruf textRect # forBounds mit unserer neuen kleineren Größe verwenden .
In textRect # forBounds verkleinern wir zuerst die Größe und dann rufen super auf.
Aufmerksam! Sie müssen super danach anrufen , nicht vorher !
Wenn Sie alle Versuche und Diskussionen auf dieser Seite sorgfältig untersuchen, ist dies genau das Problem. Beachten Sie, dass einige Lösungen "fast zu funktionieren scheinen", aber dann wird jemand berichten, dass es in bestimmten Situationen nicht funktioniert. Dies ist in der Tat der genaue Grund - verwirrenderweise müssen Sie "super danach anrufen", nicht vorher.
Wenn Sie es also "in der falschen Reihenfolge" super nennen, funktioniert es normalerweise, aber nicht für bestimmte Textlängen .
Hier ist ein genaues visuelles Beispiel für "falsches Super zuerst machen":
Beachten Sie, dass die Ränder 60,20,20,24 korrekt sind, ABER die Größenberechnung ist tatsächlich falsch, da sie mit dem Muster "super first" in textRect # forBounds durchgeführt wurde.
Fest:
Beachten Sie, dass die textRect # forBounds-Engine erst jetzt weiß, wie die Berechnung ordnungsgemäß durchgeführt wird :
Schließlich!
Auch in diesem Beispiel wird das UILabel in der typischen Situation verwendet, in der die Breite festgelegt ist. In intrinsicContentSize müssen wir also die gewünschte zusätzliche Gesamthöhe "hinzufügen". (Sie müssen die Breite in keiner Weise "hinzufügen", das wäre bedeutungslos, da es feststeht.)
Dann erhalten Sie in textRect # forBounds die "bisher vorgeschlagenen" Grenzen durch Autolayout, subtrahieren Ihre Ränder und rufen erst dann erneut die textRect # forBounds-Engine auf, dh in super, wodurch Sie ein Ergebnis erhalten.
Schließlich und einfach in drawText zeichnen Sie natürlich in derselben kleineren Box.
Puh!
Noch einmal. Beachten Sie, dass die Antworten auf diese und andere Fragen, die "fast" richtig sind, das Problem im ersten Bild oben haben - das "Super ist am falschen Ort" . Sie müssen die Größe in intrinsicContentSize erhöhen und dann in textRect # forBounds zuerst die Grenzen des ersten Vorschlags verkleinern und dann super aufrufen.
Zusammenfassung: Sie müssen in textRect # forBounds "super last " aufrufen
Das ist das Geheimnis.
Beachten Sie, dass Sie nicht zusätzlich invalidate, sizeThatFits, needLayout oder einen anderen erzwungenen Aufruf aufrufen müssen und sollten. Eine korrekte Lösung sollte im normalen Autolayout-Ziehzyklus ordnungsgemäß funktionieren.
Trinkgeld:
Wenn Sie mit Monospace-Schriftarten arbeiten, finden Sie hier einen guten Tipp: https://stackoverflow.com/a/59813420/294884
quelle
Swift 4+
Verwendung:
quelle
Swift 3 Code mit Implementierungsbeispiel
Vergessen Sie nicht, den Klassennamen UIMarginLabel in das Storyboard-Label-Objekt einzufügen. Viel Spaß beim Codieren!
quelle
Per Swift 4.2 (Xcode 10 Beta 6) "UIEdgeInsetsInsetRect" veraltet ist. Ich habe die Klasse auch öffentlich gemacht, um sie nützlicher zu machen.
quelle
sizeToFit()
sollte öffentlich sein als: "Überschreibende Instanzmethode muss so zugänglich sein wie ihr einschließender Typ"Ich habe die akzeptierte Antwort ein wenig bearbeitet. Es gibt ein Problem, wenn ein Teil des Textes verschwindet
leftInset
undrightInset
zunimmt, b / c die Breite des Etiketts wird verengt, aber die Höhe nimmt nicht wie in der Abbildung zu:Um dieses Problem zu beheben, müssen Sie die Texthöhe wie folgt neu berechnen:
und Ergebnis:
Ich hoffe, einigen Menschen in der gleichen Situation wie ich helfen zu können.
quelle
override func drawTextInRect(rect: CGRect)
wirdoverride func drawText(in rect: CGRect)
undoverride func intrinsicContentSize() -> CGSize
wirdoverride var intrinsicContentSize : CGSize
Genießen!override var intrinsicContentSize: CGSize { // .. return intrinsicSuperViewContentSize }
Eine andere Option ohne Unterklasse wäre:
text
sizeToFit()
Erhöhen Sie dann die Etikettenhöhe ein wenig, um die Polsterung zu simulieren
quelle
label.frame = CGRect( x: label.frame.origin.x - 10, y: label.frame.origin.y - 4, width: label.frame.width + 20,height: label.frame.height + 8)
die -10 und -4 für die ZentralisierungSwift 3, iOS10-Lösung:
quelle
Verwenden Sie einfach Autolayout:
Getan.
quelle
In Swift 3
bester und einfacher Weg
quelle
Unterklasse UILabel. (File-New-File-CocoaTouchClass-make-Unterklasse von UILabel).
Auf ViewController:
ODER Ordnen Sie eine benutzerdefinierte UILabel-Klasse im Storyboard als Label-Klasse zu.
quelle
Genau wie andere Antworten, aber behebe einen Fehler. Wenn dies
label.width
durch das automatische Layout gesteuert wird, wird manchmal Text zugeschnitten.quelle
Einfache Polsterung (Swift 3.0, Antwort von Alvin George):
quelle
Eine Ausarbeitung von Mundis Antwort.
dh Einbetten eines Etiketts in ein
UIView
und Erzwingen des Auffüllens durch das automatische Layout. Beispiel:Überblick:
1) Erstellen Sie ein
UIView
("Panel") und legen Sie dessen Erscheinungsbild fest.2) Erstellen Sie ein
UILabel
und fügen Sie es dem Panel hinzu.3) Fügen Sie Einschränkungen hinzu, um das Auffüllen zu erzwingen.
4) Fügen Sie das Bedienfeld Ihrer Ansichtshierarchie hinzu und positionieren Sie das Bedienfeld.
Einzelheiten:
1) Erstellen Sie die Panel-Ansicht.
2) Erstellen Sie das Etikett und fügen Sie es als Unteransicht zum Bedienfeld hinzu.
3) Fügen Sie Einschränkungen zwischen den Kanten des Etiketts und dem Bedienfeld hinzu. Dies zwingt das Bedienfeld, Abstand zum Etikett zu halten. dh "Polsterung"
Editorial: All dies von Hand zu tun ist sehr mühsam, ausführlich und fehleranfällig. Ich schlage vor, Sie wählen einen Auto-Layout-Wrapper aus Github oder schreiben selbst einen
4) Fügen Sie das Bedienfeld zu Ihrer Ansichtshierarchie hinzu und fügen Sie dann Positionierungsbeschränkungen hinzu. Umarmen Sie beispielsweise die rechte Seite einer tableViewCell wie im Beispielbild.
Hinweis: Sie müssen nur Positionsbeschränkungen hinzufügen, keine Dimensionsbeschränkungen: Das automatische Layout löst das Layout basierend auf
intrinsicContentSize
der Beschriftung und den zuvor hinzugefügten Einschränkungen.quelle
Verwenden Sie diesen Code, wenn beim Anwenden des Auffüllens Probleme mit dem Zuschneiden von Text auftreten.
quelle
Ähnlich wie bei anderen Antworten, jedoch mit einer Funkklasse, um die Polsterung dinamisch einzurichten:
quelle
Eine pragmatische Lösung besteht darin, leere Etiketten mit der gleichen Höhe und Farbe wie das Hauptetikett hinzuzufügen. Setzen Sie den vorderen / hinteren Bereich des Hauptetiketts auf Null, richten Sie die vertikalen Zentren aus und stellen Sie die Breite auf den gewünschten Rand ein.
quelle
Wenn Sie dem textRect eine 2px-Auffüllung hinzufügen möchten, gehen Sie wie folgt vor:
quelle
Wenn Sie kein @IBInspectable / @IBDesignable UILabel in Storyboard verwenden möchten oder müssen (ich denke, diese werden sowieso zu langsam gerendert), ist es sauberer, UIEdgeInsets anstelle von 4 verschiedenen CGFloats zu verwenden.
Codebeispiel für Swift 4.2:
quelle
Ziel c
Basierend auf der Antwort von Tai Le , die die Funktion in einem IB Designable implementiert, ist hier die Objective-C-Version.
Fügen Sie dies in YourLabel.h ein
Und das würde in YourLabel.m gehen
Sie können Ihre YourLabel-Insets dann direkt im Interface Builder ändern, nachdem Sie die Klasse in XIB oder Storyboard angegeben haben. Der Standardwert der Insets ist Null.
quelle
Einfacher Weg
quelle
Einfache Polsterung:
quelle
Swift 4+
quelle