UIViewController erstellt mit initWithNibName: Bundle: oder über eine IBOutlet verhalten sich anders

StackOverflow https://stackoverflow.com/questions/2257124

Frage

fand ich ein seltsames Verhalten, und möchte zu erklären, welche Behauptung mache ich das falsch ist.

In einer AppDelegate Klasse eines frisch erstellten WindowBased Projekt, ich bin das Hinzufügen eines UIViewController zum Fenster.
Ich kann es zwei verschiedene Möglichkeiten:
 - mit einem IBOutlet. In IB, ich ein UIViewController einfach instanziert, setzen Sie seine Klasse TestViewController und verband es (Szenario A des Codes).
 - die UIViewController mit Code (Szenario B) zu schaffen.

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

#define USE_IBOUTLET YES // Comment this line to switch to scenario B

#ifdef USE_IBOUTLET
    // Scenario A

    [window addSubview:theTestViewController.view];
    [window makeKeyAndVisible];
#endif


#ifndef USE_IBOUTLET
    // Scenario B

    TestViewController *theTestViewControllerProgrammatically;

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];

    [window addSubview:theTestViewControllerProgrammatically.view];

    [window makeKeyAndVisible];
#endif
}

Als ich habe jede Anpassung des Objekts in IB nicht tun, soll ich das gleiche Verhalten in beiden Szenarios hat.

Szenario A, mit der IBOutlet wie erwartet funktioniert.
Aber das Szenario B hat die folgenden Probleme:
 - Die Ansicht ist in der richtigen Position nicht (20 Pixel hoch ist, und von der Statusleiste abgedeckt)
.  - Die Ansicht der Größe nicht richtig (zum Beispiel versuchen, die in Call-Statusleiste umschalten)

Warum?

Zip-Archiv des Projekts hier um das Problem reproduzieren wollen: http : //dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

War es hilfreich?

Lösung

Das wird wirklich albern nach meinen langatmigen Antworten klingen, aber das Problem, das Sie haben einfach zu fix (programmatisch).

Diese Zeile:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

eigentlich sein sollte:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

Sie haben den Rahmen für die VC-Set von IB Einstellung, nicht durch die, die Sie programmatisch erstellt.

Wie auch immer - es ist erwähnenswert, dass alle von mir noch bewerben! Es gibt noch ein paar Dinge, die Sie programmatisch zu tun haben, wenn Sie IB keine Objekte Controller verwenden (zum Beispiel die Einrichtung der Navigationsleiste Artikel)

Paul

Andere Tipps

Ich habe in ein sehr ähnliches Problem Sie wurden mit, dass ich VC Objekte wahrgenommen werden nicht alle gleich! Das Problem, das ich habe, ist die Navigationsleiste Einstellungen vorgenommen hat, ich kann einfach nicht scheinen, um es zu tun, wenn Datei-Besitzer ein View-Controller-Objekt ist, dass ich programmatisch instanziiert. Es funktioniert nur, wenn ich unarchive IB Controller-Objekte.

heruntergeladen ich Ihr Projekt und hatte ein Spiel, um mit ihm, und es hat mir etwas mehr darüber nachzudenken, was könnte sich geht. Ich glaube, ich kann eine vernünftige Antwort geben, aber nicht sicher, ob es eine einfache Lösung ist ...

Was ich glaube, vor sich geht ist, dass Apple diese Controller-Objekte in IB erstellt haben, die etwas mehr spezialisiert sind. Ein Vorschlag dies wahr sein könnte, ist, dass IB VC-Objekte haben ein Attribut Sie können einstellen, dass keine direkte entsprechende Eigenschaft für eine UIViewController-Klasse, die ich sehen kann, so die IB-Controller-Objekte einige zusätzliche Funktionen haben können, dass nicht-IB UIViewController Subklassen kann nicht in Anspruch nehmen. Da die Objekte in einem .xib sind vollständig ‚gefriergetrocknet‘ Objekte können von Apple haben alle Arten von privaten Attribute enthalten können wir nicht in ihre IB Versionen von ihnen sehen oder verwenden - dies auf eine gewisse Wirkung haben können, wie die Objekte initialisiert .

Zum Beispiel in Ihrem MainWindow.xib, wählen Sie das IB VC Objekt und Sie können von der Inspektorpalette, wie zB „Resize View From NIB“ auf sie Attribute gesetzt. Wenn Sie diese deaktivieren Sie die Option und starten Sie Ihre Anwendung, werden Sie die VC genau erscheinen sehen, wie es in Szenario B. tut Wie Sie dieses Element nicht überprüfen kann, wenn aus der Datei Besitzer Attribute (auch wenn es als UIViewController ist ), Sie ist nicht in der Lage zu nutzen, was durch den view-Controller durchgeführt wird, um Ihnen das gewünschte Verhalten zu geben.

Das Ergebnis davon ist, dass, wenn Sie TestViewController.xib verwenden Ihre VC Objekt in Code zu initialisieren, keiner der IB spezifischen Attribute eines VC eingestellt sind, damit ein Moor-Standard UIViewController erstellt wird, und so Dinge wie die „Resize anzeigen von NIB“-Attribut und die Navigationselemente haben die Einrichtung selbst implementiert werden.

Ich habe noch keinen Weg gefunden, die Vorteile der Funktionalität zu tragen, dass das IB-View-Controller haben, wenn ich sie initWithNibName:bundle:nibBundle mit instanziiert (Ich vermute, es ist alles privat Zeug können wir keinen Zugang), aber hoffentlich kann dies gegeben haben Sie ein Ausgangspunkt ...

Natürlich könnte ich völlig falsch sein, und jemand wird mich wie ein kompletter Idiot aussehen!

Paul

Wahrscheinlich im Fall B, dass Ansicht ist nicht bekannt, das Vorhandensein einer Statusleiste. Sie müssen es entsprechend, um die Größe und stellen Sie ihre Position in der Statusleiste zu berücksichtigen. Das geschieht durch den Rahmen zu ändern (Größe) und Grenzen (Standort) Eigenschaften eines UIView.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top