Wie soll ich programmgesteuert (und in welcher Methode) ein UILabel konfigurieren, dessen Höhe von seinem Text abhängt? Ich habe versucht, es mit einer Kombination aus Storyboard und Code einzurichten, aber ohne Erfolg. Jeder empfiehlt sizeToFit
beim Einstellen lineBreakMode
und numberOfLines
. Doch egal , ob ich diesen Code setzte in viewDidLoad:
, viewDidAppear:
oder viewDidLayoutSubviews
ich kann es nicht an der Arbeit. Entweder mache ich das Feld zu klein für langen Text und es wächst nicht, oder ich mache es zu groß und es schrumpft nicht.
ios
ios6
uilabel
autolayout
Circuitlego
quelle
quelle
label.sizeToFit()
in Xcode / viewController verwenden, die Einschränkungen waren genug. hat das Label nicht in Playground erstellt . Bisher habe ich es nur auf dem Spielplatz gefundenlabel.sizeToFit()
Antworten:
Bitte beachten Sie, dass die Lösung von Matt in den meisten Fällen wie erwartet funktioniert. Aber wenn es bei Ihnen nicht funktioniert, lesen Sie bitte weiter.
Um die Größe Ihres Etiketts automatisch zu ändern, müssen Sie folgende Schritte ausführen:
Beispielsweise:
Verwenden des Interface Builder
Richten Sie vier Einschränkungen ein. Die Höhenbeschränkung ist obligatorisch.
Gehen Sie dann zum Attributinspektor des Etiketts und setzen Sie die Anzahl der Zeilen auf 0.
Wechseln Sie zum Größeninspektor des Etiketts und erhöhen Sie die vertikale ContentHuggingPriority und die vertikale ContentCompressionResistancePriority.
Wählen Sie die Höhenbeschränkung aus und bearbeiten Sie sie.
Verringern Sie die Priorität der Höhenbeschränkung.
Genießen. :) :)
quelle
preferredMaxLayoutWidth
die Breite des Etiketts ein oder stecken Sie es fest (oder die rechte und linke Seite). Das ist alles! Es wächst und schrumpft dann automatisch vertikal, um dem Inhalt zu entsprechen.Wenn in iOS 6 bei Verwendung von Autolayout die Seiten (oder die Breite) und die Oberseite eines UILabels fixiert sind, wird es automatisch vertikal vergrößert und verkleinert, um dem Inhalt zu entsprechen, ohne Code und ohne Beeinträchtigung der Kompressionsbeständigkeit oder was auch immer. Es ist ganz einfach.
In komplexeren Fällen legen Sie einfach die Beschriftungen fest
preferredMaxLayoutWidth
.In jedem Fall geschieht das Richtige automatisch.
quelle
label.sizeToFit()
Obwohl die Frage programmgesteuert lautet, nachdem ich auf dasselbe Problem gestoßen bin und lieber in Interface Builder arbeite, hielt ich es für nützlich, die vorhandenen Antworten mit einer Interface Builder-Lösung zu ergänzen.
Das erste ist zu vergessen
sizeToFit
. Das automatische Layout übernimmt dies in Ihrem Namen basierend auf der Größe des Inhalts.Das Problem ist daher, wie ein Etikett mit dem automatischen Layout an den Inhalt angepasst werden kann. Insbesondere - weil die Frage es erwähnt - Höhe. Beachten Sie, dass für die Breite dieselben Prinzipien gelten.
Beginnen wir also mit einem Beispiel für UILabel, dessen Höhe auf 41 Pixel hoch eingestellt ist:
Wie Sie oben auf dem Bildschirm sehen können,
"This is my text"
ist oben und unten eine Polsterung vorhanden. Das ist ein Auffüllen zwischen der Höhe des UILabels und seinem Inhalt, dem Text.Wenn wir die App im Simulator ausführen, sehen wir sicher dasselbe:
Wählen Sie nun das UILabel im Interface Builder aus und sehen Sie sich die Standardeinstellungen im Größeninspektor an:
Beachten Sie die oben hervorgehobene Einschränkung. Das ist die Priorität von Content Hugging . Wie Erica Sadun es im ausgezeichneten iOS Auto Layout Demystified beschreibt , ist dies:
Für uns mit dem UILabel ist der Text der Kerninhalt.
Hier kommen wir zum Kern dieses Grundszenarios. Wir haben unserer Textbezeichnung zwei Einschränkungen gegeben. Sie widersprechen sich. Man sagt "die Höhe muss gleich 41 Pixel hoch sein" . Der andere sagt „hug den Blick auf seinen Inhalt , so dass wir keine zusätzliche Polsterung haben“ . In unserem Fall sollten Sie die Ansicht an den Text anpassen, damit wir keine zusätzliche Polsterung haben.
Bei Auto Layout mit zwei verschiedenen Anweisungen, die unterschiedliche Aufgaben ausführen, muss die Laufzeit nun die eine oder andere auswählen. Es kann nicht beides. Das UILabel kann nicht beide 41 Pixel hoch sein und hat keine Polsterung.
Die Lösung erfolgt durch Angabe der Priorität. Ein Befehl muss eine höhere Priorität haben als der andere. Wenn beide Anweisungen unterschiedliche Aussagen machen und dieselbe Priorität haben, tritt eine Ausnahme auf.
Also lass es uns versuchen. Meine Höhenbeschränkung hat eine Priorität von 1000 , was erforderlich ist . Die Höhe des Inhalts beträgt 250 , was schwach ist . Was passiert, wenn wir die Priorität der Höhenbeschränkung auf 249 reduzieren ?
Jetzt können wir sehen, wie die Magie beginnt. Versuchen wir es in der Sim:
Genial! Content Hugging erreicht. Nur weil die Höhenpriorität 249 geringer ist als die Inhaltspriorität 250 . Grundsätzlich sage ich: "Die Höhe, die ich hier spezifiziere, ist weniger wichtig als die, die ich für das Umarmen von Inhalten angegeben habe . " So gewinnt der Inhalt, der umarmt.
Unter dem Strich kann das Anpassen der Beschriftung an den Text so einfach sein wie das Festlegen der Höhen- oder Breitenbeschränkung und das korrekte Festlegen dieser Priorität in Verbindung mit der inhaltlichen Prioritätsbeschränkung dieser Achse.
Wird das Äquivalent für Breite als Übung für den Leser tun!
quelle
In IOS7 bemerkte sizeToFit funktionierte auch nicht - vielleicht hilft Ihnen die Lösung auch
quelle
layoutIfNeeded
Sie hinzu, wenn Sie brauchensetNeedsUpdateConstraints
. Aber die Situation könnte etwas anders sein.Eine weitere Option, um sicherzustellen, dass die bevorzugte MaxLayoutWidth des Etiketts mit der Breite des Etiketts synchronisiert bleibt:
quelle
Ich denke, ich sollte einen Beitrag leisten, da ich eine Weile gebraucht habe, um die richtige Lösung zu finden:
Grundsätzlich sagen Sie Ihrem UILabel, dass es trotz einer festen Höhenbeschränkung die Einschränkung aufheben kann, um sich selbst zu verkleinern, um den Inhalt zu umarmen (wenn Sie beispielsweise eine einzelne Zeile haben), dies jedoch nicht kann Brechen Sie die Einschränkung, um sie größer zu machen.
quelle
In meinem Fall habe ich eine UIView-Unterklasse erstellt, die ein UILabel (unbekannter Länge) enthielt. In iOS7 war der Code unkompliziert: Legen Sie die Einschränkungen fest, sorgen Sie sich nicht um das Umarmen von Inhalten oder die Komprimierungsbeständigkeit, und alles funktionierte wie erwartet.
In iOS6 wurde das UILabel jedoch immer auf eine einzelne Zeile beschränkt. Keine der obigen Antworten hat bei mir funktioniert. Einstellungen für Inhaltsumarmung und Kompressionswiderstand wurden ignoriert. Die einzige Lösung, die ein Abschneiden verhinderte, bestand darin, eine bevorzugte MaxLayoutWidth auf dem Etikett anzubringen. Ich wusste jedoch nicht, auf welche Einstellung ich die bevorzugte Breite einstellen sollte, da die Größe der übergeordneten Ansicht unbekannt war (tatsächlich würde sie durch den Inhalt definiert).
Hier habe ich endlich die Lösung gefunden . Da ich an einer benutzerdefinierten Ansicht arbeitete, konnte ich einfach die folgende Methode hinzufügen, um die bevorzugte Layoutbreite festzulegen, nachdem die Einschränkungen einmal berechnet wurden, und sie dann neu berechnen:
quelle
Ich fügte
UILabel
programmatisch hinzu und in meinem Fall war das genug:quelle
Ich habe mit xCode6 gelöst, indem ich "Bevorzugte Breite" auf "Automatisch" gesetzt und das Etikett oben, vorne und hinten angeheftet habe
quelle
quelle
Ich bin auch auf dieses Problem mit einer UIView-Unterklasse gestoßen, die ein UILabel als eines seiner internen Elemente enthält. Selbst beim automatischen Auslegen und Ausprobieren aller empfohlenen Lösungen würde das Etikett seine Höhe nicht an den Text anpassen. In meinem Fall möchte ich immer nur, dass das Etikett eine Zeile enthält.
Für mich hat es jedenfalls funktioniert, eine erforderliche Höhenbeschränkung für das UILabel hinzuzufügen und diese manuell auf die richtige Höhe einzustellen, wenn intrinsicContentSize aufgerufen wird. Wenn Sie das UILabel nicht in einem anderen UIView enthalten haben, können Sie versuchen, UILabel in Unterklassen zu unterteilen und eine ähnliche Implementierung bereitzustellen, indem Sie zuerst die Höhenbeschränkung
festlegen und dann [super instrinsicContentSize] zurückgeben. anstelle von [self.containerview intrinsiceContentSize]; wie ich es unten tue, was spezifisch für meine UIView-Unterschicht ist.
Funktioniert jetzt perfekt unter iOS 7 und iOS 8.
quelle
intrinsicContentSize
. Die Laufzeit sollte dies basierend auf Ihren korrekt eingerichteten Einschränkungen berechnen können.Eine Lösung, die für mich funktioniert hat; Wenn Ihr UILabel eine feste Breite hat, ändern Sie die Einschränkung in Ihrer Schnittstellendatei von
constant =
bisconstant <=
quelle
In meinem Fall würde bei Verwendung der Beschriftungen in einer UITableViewCell die Größe der Beschriftung bei geändert, aber die Höhe würde die Höhe der Tabellenzellen überschreiten. Das hat bei mir funktioniert. Ich habe es laut Max MacLeod getan und dann sichergestellt, dass die Zellenhöhe auf UITableViewAutomaticDimension eingestellt ist.
Sie können dies in Ihrem init oder awakeFromNib hinzufügen.
Wählen Sie im Storyboard die Zelle aus, öffnen Sie den Größeninspektor und stellen Sie sicher, dass die Zeilenhöhe auf "Standard" eingestellt ist, indem Sie das Kontrollkästchen "Benutzerdefiniert" aktivieren.
Es gibt ein Problem in 8.0, bei dem es auch erforderlich ist, dass es im Code festgelegt wird.
quelle