2013-07-17 11 views
11

Jeśli program AutoLayout wdrażam programowo w systemie iOS, czy warto używać metody initWithFrame? Jeśli nie, jak zainicjować widok preferowanego rozmiaru?Automatyczne układanie za pomocą initWithFrame?

+1

nadal można używać 'initWithFrame' – MZimmerman6

+0

Dziękuję MZimmerman6. Powinniśmy unikać takiego kodowania lub czy jest ono właściwe? To jest moja wątpliwość. – Arock

+0

Niezależnie od tego, czy jest to właściwe, czy nie, jeśli wykonuje swoją pracę, na coś prostego, po prostu użyj go, jeśli jest to wygodne z – MZimmerman6

Odpowiedz

3

Lepiej unikać initWithFrame, chyba że nie masz wyboru. W Auto Layout podejście polega na zdefiniowaniu dwóch ograniczeń określających szerokość i wysokość. Można to zrobić na różne sposoby, ale jeśli robisz to programowo, w metodzie updateViewConstraints kontrolera widoku lub metodzie widoku updateConstraints, sprawdź, czy ograniczenia zostały już utworzone, a jeśli nie, dodaj je do widoku.

E.g.

[myConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_mySubView]-(200)-|" 
           options:0 
           metrics:nil 
           views:_myViewsDictionary]]; 

[myConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_mySubView(100)]-|" 
           options:0 
           metrics:nil 
           views:_myViewsDictionary]]; 

To powiedziawszy, lepiej zrobić to za pomocą narzędzia do tworzenia interfejsu. Kiedy już się do tego przyzwyczaisz - i trzeba się do tego przyzwyczaić - okaże się, że jest to fantastyczny przełom i znacznie lepiej niż definiowanie ograniczeń w kodzie.

+0

To nie jest do końca przekonujące. Zgadzam się, że nie ma sensu definiować ramki, kiedy jej nie użyjesz, ale Apple wciąż mówi, że 'initWithFrame' jest wyznaczonym inicjatorem dla klasy' UIView' w dokumentacji. Nazywanie 'init' wydaje się działać dobrze, ale obawiam się, że może nie być tak w przyszłych wersjach iOS. –

+0

jeśli użyjesz init, UIView zostanie zainicjowany przez initWithFrame, ale z parametrem CGRectZero. Więc skutecznie robisz to samo. Jaką ramkę dostarczysz do initWithFrame? Ramka, która nie będzie używana?Równie dobrze możesz przekazać CGRectZero, co jest dokładnie tym, co zrobiłbyś, gdybyś używał właśnie init. Ma to więcej sensu z Auto Layout, gdzie - jak już zauważyłeś - ramka zostanie zignorowana. W Swift zrobisz dużo UIView(). –

+0

To wydaje się być czymś, co nieudokumentowana metoda "init" robi dzisiaj, ale ponieważ zachowanie '[UIView init]' jest nieudokumentowane, może nie być prawdą w iOS 9, w którym to momencie istniejący kod może się zepsuć. Całkowicie zgadzam się, że podanie ramki jest głupie i że wywołanie 'init' działa dobrze dzisiaj, ale to nie zmienia faktu, że Apple nie udokumentował tego zachowania. Ponieważ pytanie brzmiało "właściwa" droga, nie jestem pewien, czy odpowiedź brzmi: "polegaj na nieudokumentowanym zachowaniu". –

0

Dlaczego nie tylko: myView = [UIView new];

Jest to to samo, co myView = [[UIView alloc] init]; Będzie działać w twoim przypadku, jeśli po jakimś czasie dodasz wymagane więzy.

+0

Powinieneś dodać to jako komentarz. Lub dodaj więcej wyjaśnień, dlaczego to powinno działać. –

+0

Zmodyfikowalem moją odpowiedź. – Ricardo

0
override init(frame: CGRect) { 
    super.init(frame: frame) 
    NSBundle.mainBundle().loadNibNamed("YourView", owner: self, options: nil) 
    self.containerView.frame = CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)) 
    self.addSubview(self.containerView) 
} 

Oto, co robię teraz. Pracuję z odrobiną starszego kodu i czasami jest czasochłonne przekształcenie wszystkiego, aby używać autolayout. Ponownie, jak stwierdził @Max MacLeod Nie używaj tego, chyba że nie masz wyboru.

+0

Chciałbym dodać, że wciąż mam stalówkę do mojego widoku. –

Powiązane problemy