2013-04-10 15 views
14

Gibt es einen einfachen Weg, der mir helfen kann, die Position abhängiger Sichten dynamisch zu ändern, indem ich ihre Inhaltsgröße verwende?UILabel sizeToFit und constraints

Ich möchte verschiedene Ansichten in der Spalte zeigen, die alle unterschiedlichen Inhalt haben. Und ich möchte, dass sie einer nach dem anderen platziert werden (ich habe mit Einschränkungen erstellt Layout, das wie folgt aussieht)

initial layout

Aber immer, wenn ich Inhalt der Etiketten ändern und rufen sizeToFit, System scheint das Layout zu ignorieren.

after size to fit call

Im Moment habe ich nur in Immobilien Höhe interessiert bin, ich weiß, dass rect beschränke auch verwendet werden können, und in der Vergangenheit habe ich schrieb dynamisch viele Kategorien auf UIView Größen zu ändern (Ich denke, jeder tat) . Aber vielleicht gibt es einen einfachen Weg, den ich nicht kenne?

+0

Überprüfen Sie diese http://stackoverflow.com/a/16009707/988169. Das funktioniert einwandfrei. – pkc456

Antwort

42

-sizeToFit sollte nicht aufgerufen werden, wenn Sie Auto-Layout verwenden. Das ist Teil des "alten" Systems.

Offenbar hat IB explizite Höhen in Ihre Abhängigkeiten eingefügt (die vertikalen Balken neben den Beschriftungen zeigen dies an). Versuchen Sie, die Beschriftungen auszuwählen und Cmd + = zu drücken, um diese zu löschen.

Für mehrzeilige Etiketten Sie werden auch die folgenden in Ihrem View-Controller tun müssen, um alles richtig funktioniert beim Drehen/Ändern der Größe der Ansicht:

- (void)updateLabelPreferredMaxLayoutWidthToCurrentWidth:(UILabel *)label 
{ 
    label.preferredMaxLayoutWidth = 
     [label alignmentRectForFrame:label.frame].size.width; 
} 

- (void)viewDidLayoutSubviews 
{ 
    [super viewDidLayoutSubviews]; 

    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label1]; 
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label2]; 
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label3]; 

    [self.view layoutSubviews]; 
} 

mehrzeilige Etiketten eine der Schwächen von Auto-Layout aus. Wir müssen preferredMaxLayoutWidth aktualisieren, um das Reflow des Etiketts zu erzwingen und seine Höhe anzupassen. Wenn die Größe der Ansicht geändert/gedreht wird, erkennt das automatische Layout nicht, dass das Etikett neu geflossen sein muss.

+0

Danke! Arbeitete für mich (ich löschte komplett und erstellte eine neue Ansicht, xcode scheint einige layoutbezogene Daten implizit zu speichern) – asdf

+0

Ja, IB + Autolayout hat momentan viele Probleme. Hoffentlich kann Apple es in Zukunft verbessern. –

+1

Können Sie Ihren Code besser erklären, insbesondere die Verwendung von 'alignmentRectForFrame'. –

-1

Das funktioniert auch. https://github.com/jszumski/auto-layout-table-cells/blob/master/DynamicCellHeights/JSLabel.m

@interface JSLabel : UILabel 

@end 

@implementation JSLabel 

- (id)init { 
    self = [super init]; 

    // required to prevent Auto Layout from compressing the label (by 1 point usually) for certain constraint solutions 
    [self setContentCompressionResistancePriority:UILayoutPriorityRequired 
              forAxis:UILayoutConstraintAxisVertical]; 

    return self; 
} 

- (void)layoutSubviews { 
    [super layoutSubviews]; 

    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds); 

    [super layoutSubviews]; 
} 

@end 
2

Wenn Sie noch Auto Layout Constraint für die Etiketten verwenden. Dies ist eine Lösung:

[self.lblBadgeValue sizeToFit]; 
self.constraintWidthBadgeLabel.constant = self.lblBadgeValue.frame.size.width; 
[self.lblBadgeValue needsUpdateConstraints]; 
[self.lblBadgeValue layoutIfNeeded]; 
  • mehr erklären:
  • sizeToFit -> Passhöhe macht Etikett, Breite mit Inhalt davon.
  • So im laufenden Betrieb benötigen Sie Constraint Höhe, oder Breite für Etiketten
  • Danach Sie Compiler sagen aktualisieren müssen wissen, dass das, was Zwang aktualisieren müssen.
  • Und am Ende müssen Sie Layout aufrufen, wenn Änderung bei Einschränkung haben.
Verwandte Themen