2013-04-05 11 views
6

Ich experimentiere mit dem Laden von NIB-Dateien in eine UIViewController.Laden einer NIB-Datei in einen UIViewController

Ich habe eine separate Nib-Datei mit dem Namen E-Mail erstellt. Zuerst bemerkte ich, dass beim Laden des View-Controllers die Methode initWithNibName nicht aufgerufen wird. Also rief ich sie aus dem viewDidLoad Verfahren manuell wie diese,

[self initWithNibName:@"Email" bundle:[NSBundle mainBundle]]; 

Es funktionierte nicht. Auch ich bekam eine Warnung, die Ausdruckresultat unbenutzt sagt.

Und ich im Internet gesucht und kam über this Artikel und implementiert, um die loadView Verfahren als wie so beschrieben,

- (void)loadView 
{ 
    [super loadView]; 

    UINib *nib = [UINib nibWithNibName:@"Email" bundle:nil]; 
    [nib instantiateWithOwner:self options:nil]; 
} 

Die Methode wird aufgerufen, aber immer noch der View-Controller ist leer!

Kann mir jemand sagen, was ich hier übersehen habe und wie das gemacht werden kann?

Vielen Dank.

UPDATE:

Zunächst einmal vielen Dank für die Antworten. Jedoch voromax und svena 's Antworten deuten darauf hin, dass ich segues entfernen und nibs automatisch laden sollte, die ich nicht sehr mag. Anils Antwort funktioniert und ich habe jetzt eine letzte Hürde.

Ich habe mehrere Nib-Dateien. Abhängig von der Benutzerauswahl sollte es eine bestimmte Spitze laden. Also, was ich versucht war, legte alle nibs innerhalb des Arrays wie so,

- (void)loadView 
{ 
    [super loadView]; 

    NSArray *nibs = [[NSArray alloc] initWithObjects: 
        [[NSBundle mainBundle] loadNibNamed:@"Facsimile" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"Email" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"Memorandum" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"ProjectMemo" owner:self options:nil], nil]; 


    self.view = [nibs objectAtIndex:0]; 
} 

und Zugang es seinen Index wie diese self.view = [nibs objectAtIndex:1]; verwenden. Aber es wirft einen Fehler * Beenden App aufgrund der nicht abgefangenen Ausnahme 'NSInvalidArgumentException', Grund: '- [__ NSArrayM _setViewDelegate:]: unerkannter Selektor an Instanz 0xd56fd20 gesendet *

Warum ist dieser Fehler auf? Wenn es nicht möglich ist, bin ich offen für Vorschläge.

Nochmals vielen Dank. Und tut mir leid, dass ich das ein bisschen herausgezogen habe.

+0

Sie immer noch nicht die Storyboards und benutzerdefinierte Logik in Ihrer Frage erwähnt, wird nicht jeder alle Kommentare lesen ... Siehe die aktualisierte Antwort – voromax

Antwort

1

Sie sollten keine Feder für den View-Controller aus den Methoden dieses View-Controllers laden.

Wenn Sie einen View-Controller von der Nib aus instanziieren möchten, tun Sie das von außerhalb des View-Controllers, normalerweise vom View-Controller, der es darstellt.

Wenn Sie nach einem Haken innerhalb der präsentierten Ansicht Controller suchen, die bereits die Outlet-Verbindungen eingerichtet haben würde, ist das Überschreiben -awakeFromNib eine beliebte Wahl. -viewDidLoad ist ein anderer.

Update # 1

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 
{ 
    if (/*do your segue identification stuff*/) { 
     UIViewController *myViewController = /*init your view controller here*/ 
     UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController]; 
     [self presentViewController:navigationController animated:YES completion:nil]; 
     return NO; 
    } 
    return YES; 
} 
+0

Es gibt einen 'UITableViewController' als den vorherigen View-Controller, also habe ich versucht, die Nib zu laden, wenn ich sie kurz vor dem Übergang instanziiere. 'NewMailViewController * newMailVC = [[NewMailViewController Alloc] initWithNibName: @" Email "Paket: nil]; newMailVC = [segue destinationViewController]; 'Aber es hat nicht funktioniert. – Isuru

+1

Von Ihrem Kommentar Ich schließe, dass Sie Storyboards verwenden. Storyboards instanziieren Ihre View-Controller für Sie und Sie laden diese Nibs nicht selbst. Gibt es einen Grund, warum Sie das Laden von Storyboards aus der nib-Version gerne fortsetzen möchten? – svena

+0

Ja, ich verwende Storyboards. Tut mir leid, ich hätte das in der Frage erwähnen sollen. Das Szenario ist so. Ich erstelle eine benutzerdefinierte Mail-App und es gibt mehrere Mail-Arten. Für jeden Mail-Typ ist die Benutzeroberfläche anders. Also habe ich eine separate Nib für jeden Mail-Typ erstellt, einen 'UITableViewController', um die Mail-Typen aufzulisten, und je nach Auswahl des Benutzers lädt er die spezifische Nib-Datei in einen' UIViewController'. – Isuru

1

Sie sollten die NIB-Datei verwenden, um den View-Controller selbst i zu instanziiert. e.

UIViewController *ctrl = [[UIViewController alloc] initWithNibName:@"Email" bundle:nil]; 

Danach können Sie diesen Controller

aktualisieren

Bei präsentieren können, wenn Sie auswählen müssen, sollten die View-Controller von der Anwendungslogik geladen werden es besser ist, alle View-Controller erstellen Überspringe in einem Storyboard die Hard-Sequence-Bindung und verwende die Methode instantiateViewControllerWithIdentifier: deiner Storyboard-Instanz, um den entsprechenden View-Controller zu erhalten und ihn manuell anzuzeigen. Ich gehe davon aus, dass Ihre Tabelle View-Controller bereits in Navigationscontroller ist:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    if (APPROPRIATE_INDEX_PATH) { 
     UIViewController *ctrl = [self.storyboard instantiateViewControllerWithIdentifier:IDENTIFIER]; 
     [self.navigationController pushViewController:ctrl animated:YES]; 
    } 
} 
+0

Es gibt einen 'UITableViewController' als der vorherige View-Controller, also habe ich versucht, die Spitze zu laden, wenn es kurz vor dem Übergang auftritt. 'NewMailViewController * newMailVC = [[NewMailViewController Alloc] initWithNibName: @" Email "Paket: nil]; newMailVC = [segue destinationViewController]; 'Aber es hat nicht funktioniert. – Isuru

+1

Sie können diesen Übergang abbrechen, indem Sie '- sentPerformSegueWithIdentifier: sender:' NO zurückgeben und Ihren Controller manuell laden. – voromax

9

den Code unten verwenden eine Ansicht von der Spitze zu laden und anzeigen, wie die Ansicht Controller verwenden

- (void)loadView 
{ 
[super loadView]; 

NSArray *nib =[[NSBundle mainBundle]loadNibNamed:@"test" owner:self options:nil]; 
self.view = [nib objectAtIndex:0]; 
} 

bearbeiten

Legen Sie eine einzelne Spitze entsprechend der Benutzerauswahl ein. Siehe Laden einer einzelnen Schreibfeder

NSArray *nib =[[NSBundle mainBundle]loadNibNamed:@"test" owner:self options:nil]; 

gibt ein Array von Objekten zurück. Anhand Ihrer aktualisierten Frage kann ich sehen, dass Sie diese Arrays in einem anderen Array speichern. Jetzt ist Ihr Nib-Array ein Array von 'Array'-Objekten.

self.view = [[nibs objectAtIndex:0]objectAtIndex:0]; 

wird funktionieren.

Aber es ist nicht gut, legen Sie eine einzelne Feder nach der Benutzer Wahl

+0

Vielen Dank für die Antwort. Diese Methode funktioniert und ich habe eine Nebenfrage. Ich habe mehrere Nib-Dateien. Abhängig von der Benutzerauswahl sollte es eine bestimmte Spitze laden. Also habe ich versucht, alle Nibs innerhalb des Arrays wie [this] (http://pastebin.com/rcpHTTSY) zu setzen und mit dem Index auf dieses 'self.view = [nibs objectAtIndex: 1];' zuzugreifen. Aber es wird eine Fehlermeldung _Terminierungs-App aufgrund der nicht abgefangenen Ausnahme 'NSInvalidArgumentException' ausgegeben, Grund: '- [__ NSArrayM _setViewDelegate:]: nicht erkannter Selektor an Instanz 0xd56fd20 gesendet' _ Fehle ich etwas oder gibt es einen anderen Weg? – Isuru

+0

Können Sie Ihren Code zusammen mit der Frage veröffentlichen? Ich kann nicht auf diese Seite zugreifen. Tatsächlich enthält das nib-Array das __loadNib__ enthält nicht nur view s, es enthält alle Steuerelemente in der nib (buttons/label ..) objectAtIndex [0] ist das Objekt der obersten Ebene (höchstwahrscheinlich eine Ansicht, wenn Sie eine einzelne Ansicht pro haben Feder). Ohne deinen Code zu sehen, kann ich nicht genau sagen, –

+0

Ich habe meine Frage oben aktualisiert. – Isuru

Verwandte Themen