2010-01-10 9 views
48

Mam aplikację z numerem UITabController, a każda karta to UINavigationController. Źródłem jednego z moich UINavigationControllers jest UIViewController.Układanie i określanie subskrybentów w module UIViewController

Wewnątrz widoku kontrolera widoku chcę ułożyć kilka subskrybentów, ale nie jestem pewien, w jaki sposób układać je w sposób, który będzie niezależny od rozdzielczości (tj. Nie będą to wartości hardcode, takie jak 320px, 480px, 44 piksele itp.).

Gdy widok jest w pełni załadowany i prezentowany na pionowym telefonie iPhone, jego wysokość będzie wynosić 367px = 480-20 (pasek stanu) - 44 (pasek nawigacji) - 49 (pasek kart).

Wewnątrz kontrolera widoku obecnie tworzę wszystkie moje subviews w ramach metody viewDidLoad. Wygląda jednak na to, że w tej metodzie aktualna wysokość widoku wynosi 460px (self.view.bounds.size.height). Więc podczas konfigurowania moich subviews nie mogę poprawnie obliczyć rozmiarów czegokolwiek.

W metodzie viewWillAppear:, widok ma wiem, że to właściwy rozmiar, ale oznaczałoby to ustawienie & obliczania klatek na podrzędny za każdym razem, gdy pojawi się widok (np zmian Tab lub popping z widoku dziecko kontrolerów na stos nawigacyjnym.

jest jedynym sposobem, aby to zrobić odpowiednio do układu w viewWillAppear:?

próbowałem za pomocą automatycznej zmiany właściwości (rodzica autoresizesSubviews & autoresizingMask), ale nie wydają się działać na wszystkich !? Czy te wchodzi w życie dopiero po skonfigurowaniu widoku, a następnie zmianie jego rozmiaru (zmiana ręczna/orientacyjna?).

Byłbym wdzięczny, gdyby ktoś mógł mi powiedzieć, dlaczego autorezjowanie nie działa, i jak najlepiej rozplanować rzeczy, nie zaklejając żadnych rozmiarów.

Odpowiedz

32

autoresizesSubviews należy ustawić w widoku macierzystym, natomiast autoresizingMask należy ustawić na widokach podrzędnych - jest to błąd, który popełniłem, aby użytkownik mógł również.

Należy dokonać subskrypcji, aby dopasować dowolny rozmiar widoku macierzystego w danym momencie, a później, gdy rozmiar nadrzędnego widoku zostanie zmieniony z 460 na 367 pikseli, wymiary podprzeglądów również zostaną zmienione zgodnie z ustawienia maski powyżej.

Jeśli to się nie powiedzie, nie ma nic złego w ustawianiu rozmiaru widoku w zakresie viewWillAppear - wpływ na wydajność robienia tego za każdym razem jest pomijalny.

Jeśli nic więcej nie działa, zawsze jest layoutSubviews: - tam, gdzie musisz, możesz zrobić układ ręczny, jest on wywoływany, gdy system wierzy, że układ może się zmienić. istnieje również setNeedsLayout: czasami przywołuję z viewWillRotate:/viewDidRotate: Ale tak naprawdę to nie powinno być potrzebne, a autorezorowanie powinno być wystarczająco dobre.

EDYCJA: Tak, aby zaimplementować niestandardową logikę układu w layoutSubviews, jak wspomnę powyżej, trzeba by podklasę UIView.

+2

Szybkie wyjaśnienie, UIViewController nie ma, ani wywoływania layoutSubviews. To jest metoda na UIView. Możesz jednak utworzyć metodę o nazwie layoutSubviews i wywołać ją z viewWillAppear: – casademora

+1

Nie ma również "loadViews". Myślę, że masz na myśli "viewDidLoad", w którym to przypadku warto wspomnieć o zwolnieniu tych widoków również w viewDidUnload. – DougW

+0

Istnieje metoda loadView, ale viewDidLoad jest zazwyczaj najbardziej wygodnym miejscem do dodawania subviews. –

40

Możesz wykonać swoją logikę układu wewnątrz viewWillLayoutSubviews z UIViewController.

-(void)viewWillLayoutSubviews{ 
    [super viewWillLayoutSubviews]; 
    // Your layout logic here 
} 

DOC: Wywoływane tuż przed wywołaniem widoku widoku kontrolera widoku. Metoda wyskakiwania. Podklasy mogą być implementowane w razie potrzeby. Wartością domyślną jest nop.

+2

jakiejkolwiek różnicy, jeśli zamiast tego używam viewDidLayoutSubviews? –