Ich habe eine benutzerdefinierte Ansicht, die layoutSubview
während der Animation keine Nachrichten erhält .
Ich habe eine Ansicht, die den Bildschirm ausfüllt. Am unteren Bildschirmrand befindet sich eine benutzerdefinierte Unteransicht, deren Größe in Interface Builder korrekt geändert wird, wenn ich die Höhe der Navigationsleiste ändere. layoutSubviews
wird aufgerufen, wenn die Ansicht erstellt wird, jedoch nie wieder. Meine Unteransichten sind korrekt angelegt. Wenn ich die Statusleiste für eingehende Anrufe ausschalte, wird die Unteransicht überhaupt layoutSubviews
nicht aufgerufen, obwohl die Hauptansicht die Größenänderung animiert.
Unter welchen Umständen heißt das layoutSubviews
eigentlich?
Ich habe autoresizesSubviews
auf NO
meine benutzerdefinierte Ansicht. Und im Interface Builder habe ich die oberen und unteren Streben und den vertikalen Pfeil eingestellt.
Ein weiterer Teil des Puzzles ist, dass das Fenster zum Schlüssel gemacht werden muss:
[window makeKeyAndVisible];
Andernfalls wird die Größe der Unteransichten nicht automatisch geändert.
quelle
layoutSubviews
. HatinitWithFrame:
UrsachelayoutSubviews
zu nennen?view1.1
, ruftlayoutSubviews
vonview1
und dannlayoutSubviews
vonview1.1
. Dieser Aufruf wird nicht unbegrenzt an die Superviews weitergegeben, sondernview1.1.1
nurlayoutSubviews
beiview1.1
undview1.1.1
. Nur zu bewegen, ohne seine Größe zu ändern, ruftlayoutSubviews
keinen von ihnen auf.view1.2
inview1
,layoutSubviews
vonview1.2
undview1
bin berufen, aberlayoutSubviews
dieview1.1
wird nicht aufgerufen. (view1.1
undview1.2
sind Unteransichten vonview1
). Das heißt, nicht alle Unteransichten der Zielansicht werden alslayoutSubviews
Methode bezeichnet .Aufbauend auf der vorherigen Antwort von @BadPirate habe ich etwas weiter experimentiert und einige Klarstellungen / Korrekturen vorgenommen. Ich habe festgestellt, dass
layoutSubviews:
eine Ansicht genau dann aufgerufen wird, wenn:Einige relevante Details:
layoutSubviews:
immer dann aufgerufen wird, wenn eine UIScrollView einen Bildlauf durchführt, da sie den Bildlauf durch Ändern des Ursprungs ihrer Grenzen ausführt.layoutSubviews:
wann die Ansicht schließlich zu einer Ansichtshierarchie hinzugefügt wird .setNeedsLayout
, wodurch ein Flag gesetzt / gehisst wird. Bei jeder Iteration der Ausführungsschleife wird für alle Ansichten in der Ansichtshierarchie dieses Flag aktiviert. Für jede Ansicht, in der das Flag angehoben gefunden wird,layoutSubviews:
wird es aufgerufen und das Flag wird zurückgesetzt. Ansichten weiter oben in der Hierarchie werden zuerst überprüft / aufgerufen.quelle
https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1
quelle
Einige der Punkte in der Antwort von BadPirate sind nur teilweise richtig:
Für
addSubView
PunktDies hängt von der automatischen Größenmaske der Ansicht (Zielansicht) ab. Wenn die automatische Größenmaske aktiviert ist, wird layoutSubview jeweils aufgerufen
addSubview
. Wenn keine Maske für die automatische Größenänderung vorhanden ist, wird layoutSubview nur aufgerufen, wenn sich die Rahmengröße der Ansicht (Zielansicht) ändert.Beispiel: Wenn Sie UIView programmgesteuert erstellt haben (standardmäßig gibt es keine Maske für die automatische Größenänderung), wird LayoutSubview nur aufgerufen, wenn sich der UIView-Frame nicht bei jedem ändert
addSubview
.Durch diese Technik erhöht sich auch die Leistung der Anwendung.
Für den Gerätedrehpunkt
Dies kann nur zutreffen, wenn sich Ihre VC in der VC-Hierarchie befindet (root at
window.rootViewController
). Dies ist der häufigste Fall. Wenn Sie in iOS 5 eine VC erstellen, diese jedoch keiner anderen VC hinzugefügt wird, wird diese VC beim Drehen des Geräts nicht bemerkt. Daher wird seine Ansicht beim Aufrufen von layoutSubviews nicht bemerkt.quelle
Ich habe die Lösung auf das Bestehen von Interface Builder zurückgeführt, dass Federn in einer Ansicht, in der die simulierten Bildschirmelemente aktiviert sind (Statusleiste usw.), nicht geändert werden können. Da die Federn für die Hauptansicht ausgeschaltet waren, konnte diese Ansicht die Größe nicht ändern und wurde daher beim Anzeigen der Anrufleiste in ihrer Gesamtheit nach unten gescrollt.
Durch Deaktivieren der simulierten Funktionen, Ändern der Größe der Ansicht und korrektes Einstellen der Federn wurde die Animation ausgeführt und meine Methode aufgerufen.
Ein zusätzliches Problem beim Debuggen besteht darin, dass der Simulator die App beendet, wenn der Anrufstatus über das Menü umgeschaltet wird. App beenden = kein Debugger.
quelle
Durch Aufrufen
[self.view setNeedsLayout];
von viewController wird viewDidLayoutSubviews aufgerufenquelle
Haben Sie sich layoutIfNeeded angesehen?
Das Dokumentations-Snippet finden Sie weiter unten. Funktioniert die Animation, wenn Sie diese Methode während der Animation explizit aufrufen?
layoutIfNeeded Legt bei Bedarf die Unteransichten fest.
Diskussion Verwenden Sie diese Methode, um das Layout von Unteransichten vor dem Zeichnen zu erzwingen.
Verfügbarkeit Verfügbar in iPhone OS 2.0 und höher.
quelle
Bei der Migration einer OpenGL-App von SDK 3 auf 4 wurde layoutSubviews nicht mehr aufgerufen. Nach vielen Versuchen und Irrtümern öffnete ich schließlich MainWindow.xib, wählte das Fensterobjekt aus, wählte im Inspektor die Registerkarte Fensterattribute (ganz links) und aktivierte "Beim Start sichtbar". Es scheint, dass es in SDK 3 immer noch einen layoutSubViews-Aufruf verursachte, aber nicht in 4.
6 Stunden Frust sind zu Ende.
quelle
Ein ziemlich dunkler, aber möglicherweise wichtiger Fall, wenn er
layoutSubviews
nie angerufen wird, ist:quelle