Quelle: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html
Intrinsische Inhaltsgröße von mehrzeiligem Text
Die intrinsische Inhaltsgröße von UILabel und NSTextField ist für mehrzeiligen Text nicht eindeutig. Die Höhe des Textes hängt von der Breite der Linien ab, die beim Lösen der Einschränkungen noch festgelegt werden muss. Um dieses Problem zu lösen, verfügen beide Klassen über eine neue Eigenschaft namens PreferredMaxLayoutWidth, die die maximale Zeilenbreite für die Berechnung der intrinsischen Inhaltsgröße angibt.
Da wir diesen Wert normalerweise nicht im Voraus kennen, müssen wir einen zweistufigen Ansatz wählen, um dies richtig zu machen. Zuerst lassen wir das automatische Layout seine Arbeit erledigen, und dann verwenden wir den resultierenden Rahmen im Layoutdurchlauf, um die bevorzugte maximale Breite zu aktualisieren und das Layout erneut auszulösen.
- (void)layoutSubviews
{
[super layoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[super layoutSubviews];
}
Der erste Aufruf von [super layoutSubviews] ist erforderlich, damit das Label seinen Frame-Set erhält, während der zweite Aufruf erforderlich ist, um das Layout nach der Änderung zu aktualisieren. Wenn wir den zweiten Aufruf weglassen, wird ein NSInternalInconsistencyException-Fehler angezeigt, da wir Änderungen am Layout-Durchlauf vorgenommen haben, die eine Aktualisierung der Einschränkungen erfordern, das Layout jedoch nicht erneut ausgelöst haben.
Wir können dies auch in einer Label-Unterklasse selbst tun:
@implementation MyLabel
- (void)layoutSubviews
{
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
@end
In diesem Fall müssen wir nicht zuerst [super layoutSubviews] aufrufen, da beim Aufruf von layoutSubviews bereits ein Frame auf dem Etikett selbst vorhanden ist.
Um diese Anpassung von der View Controller-Ebene aus vorzunehmen, schließen wir uns viewDidLayoutSubviews an. Zu diesem Zeitpunkt sind die Frames des ersten Auto-Layout-Durchlaufs bereits festgelegt, und wir können sie verwenden, um die bevorzugte maximale Breite festzulegen.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[self.view layoutIfNeeded];
}
Stellen Sie schließlich sicher, dass Sie keine explizite Höhenbeschränkung für das Etikett haben, die eine höhere Priorität als die Priorität der Inhaltskomprimierungsbeständigkeit des Etiketts hat. Andernfalls wird die berechnete Höhe des Inhalts übertroffen. Stellen Sie sicher, dass Sie alle Einschränkungen überprüfen, die sich auf die Höhe des Etiketts auswirken können.