Mam widok niestandardowy, który nie layoutSubview
wyświetla wiadomości podczas animacji.
Mam widok, który wypełnia ekran. Ma niestandardowy widok podrzędny u dołu ekranu, który zmienia rozmiar w Konstruktorze interfejsów, jeśli zmienię wysokość paska nawigacyjnego. layoutSubviews
jest wywoływany podczas tworzenia widoku, ale nigdy więcej. Moje podstrony są poprawnie ułożone. Jeśli wyłączę pasek stanu podczas połączenia, widok podrzędny layoutSubviews
nie zostanie w ogóle wywołany, nawet jeśli główny widok animuje jego zmianę rozmiaru.
W jakich okolicznościach layoutSubviews
faktycznie się nazywa?
Mam autoresizesSubviews
ustawione NO
dla mojego widoku niestandardowego. W Konstruktorze interfejsów mam górne i dolne rozpórki oraz zestaw strzałek pionowych.
Inną częścią układanki jest to, że okno musi być wykonane jako klucz:
[window makeKeyAndVisible];
w przeciwnym razie widoki podrzędne nie są automatycznie zmieniane.
źródło
layoutSubviews
. CzyinitWithFrame:
wywoływanalayoutSubviews
jest przyczyna ?view1.1
wywołujelayoutSubviews
ofview1
a następnielayoutSubviews
odview1.1
. To wywołanie nie rozprzestrzenia się w nieskończoność na superwizje, wywołując jeview1.1.1
tylkolayoutSubviews
na wywołaniachview1.1
iview1.1.1
. Samo poruszanie się bez zmiany jego rozmiaru nie wywołujelayoutSubviews
żadnego z nich.view1.2
doview1
,layoutSubviews
zview1.2
iview1
nazywane są, alelayoutSubviews
zview1.1
nie nazywa. (view1.1
iview1.2
są podstronamiview1
). Oznacza to, że nie wszystkie widoki cząstkowe widoku docelowego nazywane sąlayoutSubviews
metodą .Opierając się na poprzedniej odpowiedzi @BadPirate, eksperymentowałem trochę dalej i wymyśliłem kilka wyjaśnień / poprawek. Stwierdziłem, że
layoutSubviews:
zostanie wywołany w widoku tylko wtedy, gdy:Niektóre istotne szczegóły:
layoutSubviews:
jest wywoływany za każdym razem, gdy przewija się UIScrollView, ponieważ wykonuje przewijanie, zmieniając początek jego granic.layoutSubviews:
gdy widok zostanie ostatecznie dodany do hierarchii widoku .setNeedsLayout
, która ustawia / podnosi flagę. Każda iteracja pętli uruchamiania, dla wszystkich widoków w hierarchii widoków , ta flaga jest sprawdzana. Dla każdego widoku, w którym znaleziono flagę,layoutSubviews:
wywoływana jest na nią i flaga jest resetowana. Widoki wyżej w hierarchii będą najpierw sprawdzane / wywoływane.źródło
https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1
źródło
Niektóre punkty w odpowiedzi BadPirate są tylko częściowo prawdziwe:
Za
addSubView
punktZależy to od maski automatycznej zmiany widoku (widok docelowy). Jeśli ma WŁĄCZONĄ maskę automatyczną, dla każdego wywoływany jest layoutSubview
addSubview
. Jeśli nie ma maski automatycznej zmiany rozmiaru, layoutSubview zostanie wywołany tylko wtedy, gdy zmieni się rozmiar ramki widoku (Widok docelowy).Przykład: jeśli programowo utworzono UIView (domyślnie nie ma maski autoresize), LayoutSubview zostanie wywołany tylko wtedy, gdy ramka UIView nie zmieni się co raz
addSubview
.Dzięki tej technice zwiększa się również wydajność aplikacji.
Dla punktu obrotu urządzenia
Może to być prawdą tylko wtedy, gdy twój VC znajduje się w hierarchii VC (root at
window.rootViewController
), więc jest to najczęstszy przypadek. W iOS 5, jeśli utworzysz VC, ale nie zostanie on dodany do żadnego innego VC, to ten VC nie zostanie zauważony, gdy urządzenie się obróci. Dlatego jego widok nie zostałby zauważony przez wywołanie layoutSubviews.źródło
Prześledziłem rozwiązanie aż do nalegania Interface Buildera, że sprężyn nie można zmienić w widoku, w którym włączono symulowane elementy ekranu (pasek stanu itp.). Ponieważ sprężyny były wyłączone dla widoku głównego, widok ten nie mógł zmienić rozmiaru i dlatego został przewinięty w dół, gdy pojawił się pasek wywołania.
Wyłączenie symulowanych funkcji, a następnie zmiana rozmiaru widoku i prawidłowe ustawienie sprężyn spowodowały uruchomienie animacji i wywołanie mojej metody.
Dodatkowym problemem podczas debugowania jest to, że symulator zamyka aplikację, gdy status połączenia jest zmieniany za pomocą menu. Wyjdź z aplikacji = brak debugera.
źródło
wywołanie
[self.view setNeedsLayout];
w viewController umożliwia wywołanie viewDidLayoutSubviewsźródło
czy spojrzałeś na layoutIfNeeded?
Fragment dokumentacji znajduje się poniżej. Czy animacja działa, jeśli wywołasz tę metodę jawnie podczas animacji?
layoutIfNeeded W razie potrzeby określa widoki podrzędne.
Dyskusja Użyj tej metody, aby wymusić układ widoków podrzędnych przed rysowaniem.
Dostępność Dostępne w iPhone OS 2.0 i nowszych.
źródło
Podczas migracji aplikacji OpenGL z SDK 3 do 4, layoutSubviews nie był już nazywany. Po wielu próbach i błędach w końcu otworzyłem MainWindow.xib, wybrałem obiekt Window, w inspektorze wybrałem zakładkę Window Attributes (skrajnie lewy) i zaznaczyłem „Visible at launch”. Wygląda na to, że w SDK 3 nadal wywoływał wywołanie layoutSubViews, ale nie w 4.
Zakończono 6 godzin frustracji.
źródło
Dość niejasnym, ale potencjalnie ważnym przypadkiem, gdy
layoutSubviews
nigdy nie zostanie wywołany, jest:źródło