2013-06-30 5 views
13

Próbuję lepiej zrozumieć działanie widoków kontenera w serii ujęć. Wygląda na to, że widok kontenera wymusi zmianę jego podglądu w celu wypełnienia kontenera.Co powoduje, że widok kontenera zachowuje ramkę widoku podrzędnego, aby dopasować ją do granic?

storyboard relationships

widzę żadnych ograniczeń, które wyjaśni, i nie ma wzmianki o tym, co to jest klasa. Wygląda jak magia storyboardów.

constraints

Zakładam, że widok pojemnik musi być podklasą UIView, a ja mam dziką przypuszczenie i przejąć jego nazwie UIContainerView, ale przeszukując rentowności dokumentacji tylko dwa wyniki.

search results

Więc jak to działa?

+0

Nie sądzę, że jest to podklasa, myślę, że to tylko UIView, a za kulisami, Xcode ustawia ramkę wbudowanego kontrolera, aby był równy granicom widoku kontenera. – rdelmar

Odpowiedz

25

Edytor storyboardów (Interface Builder) zachowuje osadzony widok frame ustawiony na widok pojemnika bounds podczas edycji. Tak więc, gdy scenorys jest zapisywany do pliku, sparametryzowane rozmiary widoków są identyczne. Dzieje się tak bez względu na to, czy urządzanie storyboarda ma włączony układ automatyczny.

Widok najwyższego poziomu każdego kontrolera widoku w scenorysie ma również ustawioną maskę autouzupełniania na UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight, ponownie niezależnie od tego, czy w scenorysie włączony jest układ automatyczny.

Jeśli włączony jest układ automatyczny, każdy widok najwyższego poziomu ma translatesAutoresizingMaskToConstraints ustawiony na YES. To różni się od wszystkich potomków tych widoków najwyższego poziomu. Wszyscy potomkowie mają translatesAutoresizingMaskToConstraints ustawiony na NO.

Relacja osadzania reprezentowana jest jako klasa klasy UIStoryboardEmbedSegue. (Jest to klasa prywatna, nie jest częścią publicznego interfejsu API.)

Po odebraniu przez UIStoryboardEmbedSegue wiadomości perform ładuje ona widok kontrolera widoku docelowego i dodaje go jako widok podz góry widoku kontenera. Następnie ustawia osadzony widok: autoresizingMask do UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight. Jest to zbędne, ponieważ twórca interfejsu już tak ustawił to w scenorysie.

Następnie sprawdza się osadzony widok translatesAutoresizingMaskToConstraints. Jest to również zbędne, ponieważ program Interface Builder ustawił go na YES.

Jeżeli osadzony widok na translatesAutoresizingMaskToConstraints jest YES, perform ustawia wbudowany widok na frame do pojemnika widok na bounds. Ponownie, zbędne.

Jeżeli osadzony widok na translatesAutoresizingMaskToConstraints jest NO, perform dodaje ograniczenia H:|[childView]| i V:|[childView]|, zmuszając wbudowanego widok wypełnić widoku kontenera. (Tak, w rzeczywistości używa języka w formacie wizualnym.) Ta gałąź nie powinna zostać osiągnięta.

Gdy widok ma translatesAutoresizingMaskToConstraints zestaw do YES, układ automatycznej automatycznie dodaje ograniczeń typu NSAutoresizingMaskLayoutConstraint i utrzymuje je na bieżąco, kiedy zmienić pogląd na frame. Na przykład, widok z okna głównego jest wykonana, aby wypełnić okno za pomocą automatycznej zmiany ograniczenia:

<NSAutoresizingMaskLayoutConstraint:0x7555d00 h=-&- v=-&- UIView:0x7671780.midX == UIWindow:0x7551010.midX>, 
<NSAutoresizingMaskLayoutConstraint:0x7555de0 h=-&- v=-&- UIView:0x7671780.width == UIWindow:0x7551010.width>, 
<NSAutoresizingMaskLayoutConstraint:0x7555eb0 h=-&- v=-&- UIView:0x7671780.midY == UIWindow:0x7551010.midY + 10>, 
<NSAutoresizingMaskLayoutConstraint:0x7555ef0 h=-&- v=-&- UIView:0x7671780.height == UIWindow:0x7551010.height - 20> 

Więc to, co „powoduje Container View zachować ramkę jego podrzędne widoku danych, by dopasować swoje granice”.

Zorientowałem się, patrząc na plik .storyboard (jest to zaskakująco czytelny XML), i patrząc na -[UIStoryboardEmbedSegue perform] w Hopper.

Jak, dlaczego mają one zbędne kontrole, mogę wymyślić kilka prawdopodobnych powodów:

  1. funta (być może w wersji pre-release) nie zawsze nie skonfigurować właściwości przeglądać sposób robi teraz, więc kod nie jest zbędny podczas ładowania starych scenorysów.

  2. Apple ma wewnętrzne narzędzia, które generują storyboardy inaczej niż IB.

  3. Kod jest przeznaczony dla przyszłej zgodności z przyszłymi wersjami IB, które pozwalają widokom scenopisów na najwyższym poziomie mieć różne właściwości.

+3

Świetne wyjaśnienie! Czy oznacza to również, że przy korzystaniu z storyboardu nie jest możliwe, aby zawartość widoku kontenera decydowała o wysokości widoku kontenera (który ma nałożone ograniczenia centrowania widoku w widoku, w którym jest osadzony)? –

+1

@Scott Wygląda na to, że powinieneś przeczytać moją odpowiedź na [to pytanie] (http://stackoverflow.com/q/17376240/77567). –

+0

Doskonała odpowiedź i doskonałe wykorzystanie Hoppera – malhal

0

Utworzenie projektu testowego i przejrzenie kodu daje dość jasne pojęcie o tym, jak to jest realizowane. Sam widok kontenera jest zwykłym UIView. W ramach procesu loadView kontrolerów widok kontenerów jest tworzony z ustawieniami ograniczeń w scenorysie. Następnie wykonywany jest osadzony kontroler segue. Spowoduje to utworzenie kontrolera widoku podrzędnego, który ma swój widok dodany jako widok podz góry widoku kontenera, oraz odpowiednie ustawienia wiązań układu, aby widok podrzędny wypełniał kontener. To naprawdę.

+0

Tak, ale oczywiście nie działa. Po zmianie rozmiaru kontenera widoki widoków podrzędnych nie pasują do nowej granicy. –