UIViewController drehen Methoden

stimmen
17

Welche Aufgabe ist für dipatching die verantwortlichen UIViewControllerRotationsverfahren Anrufe, das heißt:

  • shouldAutorotateToInterfaceOrientation:
  • willRotateToInterfaceOrientation:duration:
  • willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
  • willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
  • didRotateFromInterfaceOrientation:

Ich stelle mir vor es ist UIApplication(aber vielleicht die AppDelegate oder UIWindow).

Die nächste Frage ist , wie sich das Objekt wissen , welche UIViewControllerzu reden?

Woher weiß er , was UIViewControllerseine Ansicht als Subview des Fensters hat?

Gibt es eine Nachricht , die Sie oder eine Eigenschaft , senden Sie (eines Objekts) festlegen können, die „Aktiv“ setzt UIViewControllerfür die App?

Veröffentlicht am 14/02/2009 um 00:50
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
13

Es scheint , dass UIApplicationeine Nachricht an den aktiven View - Controller - Dispatching.

Aber wie sieht Ihre View-Controller-Instanz diese Nachrichten erhalten?

Die Nachricht wird an den ersten View - Controller weitergeleitet , dessen Blicks auf die hinzugefügt wurde UIWindowInstanz.

Dies läuft darauf hinaus, 3 Grundszenarien nach unten:

  1. Der Viewcontroller , deren Ansicht ist direkt mit der zusätzlichen UIWindow Instanz (Einzelansicht app)

  2. Die Navigation-Controller in einer Navigation-basierte Anwendung, dann ist die Navigation-Controller leitet die Nachricht an den aktiven Ansichten Controller anzuzeigen.

  3. Die Lasche Leiste Controller in einer Registerleiste basierten Anwendung, dann wird die Registerleiste Controller leitet die Nachricht an die aktiven Ansichten Controller anzuzeigen (oder die aktive Navigationssteuerung).

Das Problem , das Sie haben, ist , wenn Sie eine Anwendung mit mehreren Ansichten zu bauen, aber keine Navigation Controller oder Tab Bar - Controller verwenden. Wenn Sie Ansichten wechseln in die und aus der UIWindowInstanz manuell, werden Sie diese Nachrichten nicht zuverlässig empfangen. Dies ist ähnlich wie diese an jedem Beitrag: iPhone viewWillAppear nicht feuern

Verwenden Sie einfach Apples Konventionen für mehrere Ansichten und Sie in Ordnung sein. Hoffe, dass dies spart jemand eine oder zwei Stunden

Beantwortet am 19/02/2009 um 05:49
quelle vom benutzer

stimmen
4

Woher weiß er, welche UIViewController seine Ansicht als Subview des Fensters hat?

UIViewController Klasse behält eine statische Karte zwischen den Ansichten und ihren View-Controller. Diese Karte ist in einigen wichtigen Stellen im Cocoatouch abgefragt. Insbesondere [UIView nextResponder] fragt er und gibt die Steuerung, wenn gefunden.

Ich denke, UIWindow macht das gleiche Lookup mit seiner Stammansicht zu wissen, welche Controller weiterleiten Rotation Ereignisse. Wird dies das nächste Mal prüfe ich etwas suchen, werde in der Demontage auf. (Ich habe einige Zeit Reverse-Engineering Cocoatouch verbracht, zu verstehen, wie die Dinge dort arbeiten.)

Beantwortet am 06/05/2009 um 12:15
quelle vom benutzer

stimmen
4

Das ist alle Magie man dagegen tun not Ever Sorgen. Fügen Sie einfach zum Fenster Stammansicht Ihres Controllers - oder eine Tab-Leiste oder Navigation-Controller bekommen es für Sie zu tun - und es wird diese Nachrichten empfangen.

(Aber wenn Sie mit dem Debugger herumzustochern, könnten Sie zu dem gleichen Schluss kommen ich habe. Es gibt eine Art interne Tabelle Abbilden jeder Ansicht des Controllers an den Controller zurück, und die Nachrichten werden auf diesem versandten basiert)


Aktualisieren: Das war wirklich privat Magie im Jahr 2009 , als ich zum ersten Mal dieser Antwort schrieb, aber spätere Änderungen an iOS haben die APIs dahinter öffentlich gemacht. Der Root - View - Controller ist nun durch die UIWindow.rootViewControllerEigenschaft und der Baum des Nachkommen Ansicht - Controller ist mit der gebildeten UIViewController.childViewControllersEigenschaft.

Geordneten Ansicht Controller ist verantwortlich für ihre Kinder von Orientierungsänderungen zu benachrichtigen. (Ich bin nicht sicher , wie der Wurzel - View - Controller gemeldet wird, aber man kann einen Haltepunkt setzen und selbst herausfinden.) Das -shouldAutomaticallyForwardRotationMethodsVerfahren entscheidet , ob UIViewController wird dies für Sie tut. Wenn es gibt NO, werden Sie verantwortlich für das Tun so in Ihren -willRotateToInterfaceOrientation:duration:, -willAnimateRotationToInterfaceOrientation:duration:und -didRotateFromInterfaceOrientation:Methoden.

Beantwortet am 14/02/2009 um 01:42
quelle vom benutzer

stimmen
1

Ich habe ein ähnliches Problem.

Ich habe ein Spiel in Querformat arbeitet (links und rechts Landschaft).

Um eine Multi-View-Anwendung ich eine Wurzel UIViewController verwenden zu verwalten, dh einen Dummy-Uiviewcontroller mit einem UIView, die nichts tut. Ich füge dann alle anderen UIView, um es als ein Subview.

Wenn Sie die App starten, dreht sich der Emulator schnell zu einem Hochformat, und ich bekomme alle meine Ansichten mit seinen Rahmen Immobilien suchen, wie (0, -80320480). Daraus ergibt sich die Ansicht von einem 160 X 320 Rechteck auf der rechten Seite abgeschnitten werden.

Ich habe bemerkt, dass die - ShouldAutorotateToInterfaceOrientation: Methode jedes subview nur einmal aufgerufen wird, und das geschieht, wenn es um die Stammansicht hinzugefügt wird. Später, wenn die Vorrichtung gedreht wird, nur die Stammansicht bekommt ist es Methode aufgerufen.

Es überrascht nicht, eine der - willAnimate * Methoden Anrufe wird nur in die Stammansicht gesendet, so, Definieren jedes dieser Verfahren in Subviews sinnlos.

Diese Methoden werden als jedes Mal die Orientierung in eine Orientierung geändert angenommen durch die - ShouldAutorotateToInterfaceOrientation: Methode. so dass ich dachte, ich könnte meine Subviews' -Rahmen Eigenschaft von dort chnage.

Um dies zu erreichen, definierte ich die folgende Methode in meiner RootViewController Klasse:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
    subview1_ViewController.view.frame = CGRectMake(0,0,480,320);
    subview2_ViewController.view.frame = CGRectMake(0,0,480,320);
        ...
}

Ich verstehe nicht, warum die Rahmen-Eigenschaft nicht aktualisiert wird, aber ich weiß, diese Problemumgehung funktioniert.

Hoffe das hilft....

Beantwortet am 25/03/2010 um 05:20
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more