2013-04-10 16 views
14

Czy istnieje prosty sposób, który może dynamicznie zmieniać pozycję zależnych widoków przy użyciu rozmiaru zawartości?UILabel sizeToFit i ograniczenia

Chcę wyświetlić kilka widoków w kolumnie, które mają różną zawartość. I chcę, żeby być umieszczone jeden za drugim (I stworzyliśmy układ przy użyciu ograniczeń, które wygląda tak)

initial layout

Ale ilekroć zmienić treść etykiet i nazywają sizeToFit, system wydaje się ignorować układ.

after size to fit call

W tej chwili jestem zainteresowany tylko w nieruchomości wysokość, wiem, że ograniczanie rect można stosować też w przeszłości pisałem wiele kategorii na UIView dynamicznie zmieniać rozmiary (chyba każdy robił) . Ale może jest prosty sposób, którego nie znam?

+0

Sprawdź to http://stackoverflow.com/a/16009707/988169. Działa to doskonale. – pkc456

Odpowiedz

42

-sizeToFit nie powinien być wywoływany, jeśli używasz automatycznego układu. To część "starego" systemu.

Wygląda na to, że IB wprowadził wyraźne szczyty do wiązań (pionowe paski obok etykiet wskazują na to). Spróbuj wybrać etykiety i naciśnij Cmd + =, aby je wyczyścić.

Dla multilinii etykiet Potrzebny będzie również wykonać następujące czynności w kontrolerze widoku, aby wszystko działało poprawnie podczas obracania/zmiany rozmiaru widoku:

- (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]; 
} 

wielowierszowe etykiety narażają jedna ze słabości automatycznego układu. Musimy zaktualizować preferredMaxLayoutWidth, aby zmusić etykietę do ponownego naświetlania i dostosować jej wysokość, w przeciwnym razie, jeśli widok zostanie zmieniony/obrócony, automatyczny układ nie zdaje sobie sprawy, że etykieta musi zostać ponownie przepuszczona i zmieniona.

+0

Dziękujemy! Pracowałem dla mnie (całkowicie usunąłem i utworzyłem nowy widok, xcode wydaje się pośrednio przechowywać pewne dane związane z układem) – asdf

+0

Tak, IB + autolayout ma teraz wiele problemów. Mam nadzieję, że Apple może ją poprawić w przyszłości. –

+1

Czy możesz wyjaśnić swój kod bardziej, szczególnie użycie 'alignmentRectForFrame'. –

-1

To też działa. 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

Jeśli nadal chcesz korzystać z automatycznego układu ograniczenie dla etykiety. Jest to rozwiązanie:

[self.lblBadgeValue sizeToFit]; 
self.constraintWidthBadgeLabel.constant = self.lblBadgeValue.frame.size.width; 
[self.lblBadgeValue needsUpdateConstraints]; 
[self.lblBadgeValue layoutIfNeeded]; 
  • Wyjaśnij więcej:
  • sizeToFit -> make etykieta dopasowanie wysokości, szerokość z treści niego.
  • Więc w czasie wykonywania trzeba aktualizować wysokość ograniczeń, lub szerokości na etykiecie
  • Po tym trzeba powiedzieć, że kompilator wiedzieć co trzeba zaktualizować ograniczenie.
  • I na koniec należy zadzwonić pod numer , jeśli zmieniono ograniczenie.
Powiązane problemy