Frage

Ich habe eine benutzerdefinierte Ansicht, die nicht angezeigt wird layoutSubview Nachrichten während der Animation.

Ich habe eine Ansicht, die den Bildschirm ausfüllt.Es verfügt über eine benutzerdefinierte Unteransicht am unteren Bildschirmrand, deren Größe im Interface Builder korrekt angepasst wird, wenn ich die Höhe der Navigationsleiste ändere. layoutSubviews wird aufgerufen, wenn die Ansicht erstellt wird, aber nie wieder.Meine Unteransichten sind korrekt angeordnet.Wenn ich die Anrufstatusleiste ausschalte, wird die Unteransicht angezeigt layoutSubviews wird überhaupt nicht aufgerufen, obwohl die Hauptansicht ihre Größenänderung animiert.

Unter welchen Umständen ist layoutSubviews eigentlich angerufen?

Ich habe autoresizesSubviews einstellen NO für meine benutzerdefinierte Ansicht.Und im Interface Builder habe ich die oberen und unteren Streben und den vertikalen Pfeil festgelegt.


Ein weiterer Teil des Rätsels besteht darin, dass das Fenster zum Schlüssel gemacht werden muss:

[window makeKeyAndVisible];

Andernfalls wird die Größe der Unteransichten nicht automatisch geändert.

War es hilfreich?

Lösung 5

raupen ich die Lösung auf Interface Builder Beharren, die Federn nicht auf eine Ansicht geändert werden, dass die simulierten Bildschirmelemente eingeschaltet (Statusleiste, etc.) hat. Da die Federn für die Hauptansicht waren ausgeschaltet, könnte diese Ansicht nicht Größe ändern und daher wurde in seiner Gesamtheit nach unten gescrollt, wenn die in-Call-Bar erschien.

die simulierten Funktionen ausschalten, dann die Ansicht Ändern der Größe und die Federn Einstellung richtig die Animation verursachte aufzutreten und meine Methode aufgerufen werden.

Ein zusätzliches Problem bei der Fehleranalyse ist, dass der Simulator die App beendet wird, wenn der in-Call-Status über das Menü umgeschaltet wird. Beenden app = kein Debugger.

Andere Tipps

hatte ich eine ähnliche Frage, aber war mit der Antwort nicht zufrieden (oder alle, die ich im Netz finden konnte), so habe ich versucht, es in der Praxis, und hier ist, was ich habe:

  • init verursacht keine layoutSubviews zu werden genannt (duh)
  • addSubview: Ursachen layoutSubviews zu auf dem heißen Ansicht hinzugefügt wird, die Ansicht, es wird bis (Zielansicht) hinzugefügt, und das ganze Subviews des Ziels
  • Ansicht setFrame intelligent ruft layoutSubviews auf die Ansicht zu haben eingestellt sein Rahmen nur wenn die Größenparameter des Rahmens ist, verschiedene
  • Scrollen eine UIScrollView Ursachen layoutSubviews auf genannt werden die Scrollview und seine Superview
  • Drehen einer Vorrichtung nur Anrufe layoutSubview auf der Elternansicht (die reagiert Viewcontrollers primären Ansicht)
  • eine Ansicht Ändern der Größe wird layoutSubviews auf seine Superview rufen

Meine Ergebnisse - http: // blog. logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/

Auf der Grundlage der vorherigen Antwort von @BadPirate, experimentierte ich ein bisschen weiter und kam mit einigen Präzisierungen / Korrekturen nach oben. Ich fand, dass layoutSubviews: wird auf einer Ansicht aufgerufen werden, wenn und nur wenn:

  • Die eigenen Grenzen (nicht Rahmen) geändert.
  • Die Grenzen eines seiner direkten Subviews geändert.
  • ein Subview der Ansicht hinzugefügt oder aus der Ansicht entfernt.

Einige relevante Details:

  • Die Grenzen betrachtet werden nur geändert, wenn der neue Wert ist anders, mit einer anderen Herkunft . Beachten Sie speziell ist, warum layoutSubviews:, wenn ein UIScrollView scrollt genannt wird, wie es das Scrollen führt durch seine Grenzen Ursprung zu ändern.
  • Ändern der Rahmen wird nur die Grenzen ändern, wenn die Größe geändert hat, da dies das einzige, was an die Grenzen Eigentum propagiert wird.
  • Eine Änderung der Grenzen einer Ansicht, die noch nicht in einer Ansicht Hierarchie wird in einem Aufruf zur Folge layoutSubviews: , wenn die Ansicht schließlich zu einer Ansicht Hierarchie hinzugefügt wird .
  • Und nur der Vollständigkeit halber: diese Trigger nicht direkt rufen layoutSubviews, sondern rufen setNeedsLayout, die Sätze / wirft eine Flagge. Jede Iteration der Laufschleife für alle Ansichten in der Ansichtshierarchie , wird dieser Flag geprüft. Für jede Ansicht, in der die Flagge gehisst gefunden wird, wird layoutSubviews: sie aufgefordert hat, und das Flag wird zurückgesetzt. Ansichten weiter oben in der Hierarchie wird zuerst geprüft / aufgerufen werden.

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1

Layout -Änderungen können immer dann auftreten, wenn eines der folgenden Ereignisse in einer Ansicht auftritt:

A.Die Größe des Begrenzungsrechtecks ​​einer Ansicht ändert sich.
B.Es kommt zu einer Änderung der Schnittstellenausrichtung, die normalerweise eine Änderung des Begrenzungsrechtecks ​​der Stammansicht auslöst.
C.Der Satz von Core Animation-Unterebenen, die mit der Ebene der Ansicht verknüpft sind, ändert sich und erfordert ein Layout.
D.Ihre Anwendung erzwingt die Ausführung des Layouts durch Aufrufen vonsetNeedsLayoutoderlayoutIfNeededMethode einer Ansicht.
e.Ihre Anwendung erzwingt das Layout durch Aufrufen vonsetNeedsLayoutMethode des zugrunde liegenden Ebenenobjekts der Ansicht.

Einige der Punkte in BadPirate Antwort ist nur teilweise wahr:

  1. Für addSubView Punkt

      

    addSubview verursacht layoutSubviews auf der Ansicht hinzugefügt aufgerufen werden, die Ansicht, es zu (Zielansicht) hinzugefügt werden wird und alle Subviews des Ziels.

    Es hängt von der (Zielansicht) Autoresize Maske Ansicht. Wenn es Autoresize Maske auf hat, wird layoutSubview auf jedem addSubview aufgerufen werden. Wenn es keine Autoresize Maske dann wird layoutSubview nur aufgerufen werden, wenn die Ansicht der (Ziel View) Bildgröße ändert.

    Beispiel: Wenn Sie UIView programmatisch erstellt (es hat standardmäßig keine Autoresize Maske), wird LayoutSubview nur aufgerufen werden, wenn UIView Rahmen nicht auf jedem addSubview ändert

    .

    Es ist durch diese Technik, die die Leistung der Anwendung auch erhöht.

  2. Für das Gerät Drehpunkt

      

    Rotierende nur ein Gerät layoutSubview auf der Elternansicht aufruft (die Reaktion Viewcontroller primäre Ansicht)

    Dies wahr sein kann nur, wenn Ihr VC in der VC-Hierarchie (root bei window.rootViewController), auch dies ist häufigste Fall. In iOS 5, wenn Sie einen VC schaffen, aber es ist nicht in jedem anderen VC hinzugefügt, dann wäre dies VC bekommen nicht, wenn das Gerät drehen bemerkt. Daher würde ihre Ansicht nach nicht durch den Aufruf layoutSubviews bemerkt.

Berufung [self.view setNeedsLayout]; in Viewcontroller es viewDidLayoutSubviews

nennen macht

Sie haben bei layoutIfNeeded geschaut?

Die Dokumentation Schnipsel ist unten. Ist die Animation Arbeit, wenn Sie diese Methode aufrufen explizit während der Animation?

layoutIfNeeded Ordnet die Subviews, wenn nötig.

- (void)layoutIfNeeded

Diskussion Verwenden Sie diese Methode zu zwingen, das Layout Subviews vor dem Zeichnen.

Verfügbarkeit Erhältlich in iPhone OS 2.0 und höher.

Wenn Sie einen OpenGL-App von SDK 3 bis 4 Migration wurde layoutSubviews nicht mehr genannt. Nach einer Menge von Versuch und Irrtum ich MainWindow.xib schließlich geöffnet, ausgewählt, um das Window-Objekt, in dem Inspektor wählte Fensterattribute Registerkarte (ganz links) und überprüfte „Visible beim Start“. Es scheint, dass in SDK 3 noch einen layoutSubviews Anruf führen, nicht jedoch in 4.

6 Stunden Frustration ein Ende setzen.

Ein ziemlich dunkel, aber potenziell wichtiger Fall, wenn layoutSubviews nie aufgerufen wird, ist:

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top