web-dev-qa-db-de.com

Verwenden mehrerer Storyboards in iOS

Mein Ziel ist es, eine Anwendung mit Registerkarten zu erstellen. Anschließend wird die Ansicht für jede Registerkarte in separaten Storyboards erstellt.

Storyboard screenshot

Mein Mainstoryboard ist eine Registerkartenansicht.

Dann erstelle ich ein sekundäres Storyboard (Storyboard 2) mit 2 View Controllern. Der erste Ansichts-Controller (der auch als anfänglich markiert ist) verfügt über eine Schaltfläche und wechselt (modal) zur zweiten Ansicht. First view controller

Ich habe es geschafft, die Ansicht zu laden, indem ich loadView aus Storyboard 2 untergeordnet und überschrieben habe. loadView override

Hier ist die Simulatorausgabe.

Simulator

Wenn ich auf die Schaltfläche "Klick mich" klicke, erhalte ich ein EXC_BAD_ACCESS. Das Segue funktioniert nicht, anscheinend wird das zweite Storyboard nicht vollständig geladen.

Hat jemand versucht, dies zu tun und es zum Laufen zu bringen? Es gibt ein Youtube-Video von SkillMaster.net, aber er demonstriert nicht, ob eine Überblendung unter dem sekundären Storyboard funktioniert. Das Video ist hier: http://youtu.be/D4_twoYvB4M

Vielen Dank für jede Eingabe und Hilfe!

Screenshots:

74

Dies sind die besten Artikel, die ich auf mehreren Storyboards gesehen habe.

Er sagt dir nicht nur, wie man ein neues Storyboard im Code erstellt

  • empfiehlt mehrere Storyboards in der Praxis (modularer Code)
  • erläutert die Verwendung von XIBs im Vergleich zu Storyboards (XIBs halten Ansichten, Storboards basieren auf Controllern).
  • bietet eine Klasse zum Verknüpfen von Storyboards mit Segues auf Github

Beachten Sie, dass dieser letzte Punkt wichtig ist, da der Hauptnachteil mehrerer Storyboards darin besteht, dass Sie sie normalerweise nicht mit Segues verknüpfen können, die Robs-Bibliothek dies jedoch mit ein wenig Fudging ermöglicht

Siehe auch das besprochene hier

79
Rhubarb

Das OP bearbeitete seine Frage mit der Antwort:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"HelpStoryboard" bundle:nil];
UIViewController* initialHelpView = [storyboard instantiateInitialViewController];

initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:initialHelpView animated:YES];

Natürlich ist es sinnvoll, von wo aus Sie dies aufrufen, da Sie möglicherweise 2 Storyboards und deren Ansichtsstapel im Speicher haben. Also wahrscheinlich am besten, wenn Sie diesen Code von außerhalb der View-Controller des anderen Storyboards aufrufen.

44
pchap10k

Ich habe den von Rhubarb vorgeschlagenen Ansatz RBStoryboardLink untersucht. Diese Implementierung ersetzt die Eigenschaften des Ansichtscontrollers, die merkwürdig aussehen. Ich glaube, ich habe den Weg gefunden, dies zu vermeiden. Hier ist das Demo-Projekt .

Navigationssteuerungen

Navigations-Controller könnten einfach einen referenzierten View-Controller als Root festlegen. Die Implementierung eines solchen Ansichtscontrollers kann folgendermaßen aussehen:

@interface ExternNavigationController : UINavigationController

@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;

@end

@implementation ExternNavigationController

- (void)awakeFromNib
{
    NSAssert(self.storyboardName, @"storyboardName is required");

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:self.storyboardName bundle:nil];
    UIViewController *vc = self.sceneIdentifier
        ? [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier]
        : [storyboard instantiateInitialViewController];

    self.viewControllers = @[vc];
}

@end

Controller anzeigen

Probleme beginnen, wenn Sie einen in einem externen Storyboard definierten View Controller übertragen möchten. Dies ist der Fall, wenn Eigenschaften kopiert werden. Stattdessen können wir ein benutzerdefiniertes Segue implementieren, das einen gefälschten Ziel-Controller durch einen echten aus einem externen Storyboard ersetzt.

@interface ExternStoryboardSegue : UIStoryboardSegue

@end

@implementation ExternStoryboardSegue

- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(ExternViewController *)destination
{
    NSAssert(destination.storyboardName, @"storyboardName is required");

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:destination.storyboardName bundle:nil];
    UIViewController *vc = destination.sceneIdentifier
        ? [storyboard instantiateViewControllerWithIdentifier:destination.sceneIdentifier]
        : [storyboard instantiateInitialViewController];

    return [super initWithIdentifier:identifier source:source destination:vc];
}

- (void)perform
{
    [[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:YES];
}

@end

ExternViewController wird als Platzhalter verwendet und enthält die für die Ersetzung erforderlichen Eigenschaften (storyboardName und sceneIdentifier).

@interface ExternViewController : UIViewController

@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;

@end

@implementation ExternViewController

@end

Wir müssen diese Eigenschaften und die benutzerdefinierte Klasse für den Platzhalter-Ansichtscontroller festlegen. Außerdem können Sie den View Controller mit ExternStoryboardSegue verknüpfen.

IB screenshot

19
vokilam

Aus einer meiner XIB-Dateien navigiere ich in einen komplizierteren Teil der Benutzeroberfläche und verwende für diesen Teil ein Storyboard. Ein Knopf in meinem XIB navigiert zum Storyboard. Der Code, den ich dafür habe, ist:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardIdentifier" bundle:nil];
UIViewController* myStoryBoardInitialViewController = [storyboard instantiateInitialViewController];

[self.navigationController pushViewController:myStoryBoardInitialViewController animated:YES];

Dadurch wird mein StoryBoard erfolgreich in die Ansicht verschoben. Der obige Code wird über die Aktion "Touch Up Inside" aufgerufen.

16

Ab Xcode 7 (und zurück auf iOS8 portiert) können Sie jetzt Storyboard-Referenzen haben. Es wurde in dieser WWDC 2015 Sitzung erwähnt (es beginnt ungefähr in der ersten Stunde, über sie zu sprechen). Grundsätzlich müssen Sie nur die ViewController auswählen, die Sie in ein separates Storyboard verschieben möchten, und dann auf Editor-> Auf Storyboard umgestalten ... klicken. Gib ihm einen Namen und voila:

enter image description here

Bitte beachten Sie, dass Sie, wenn Sie VCs hatten, die in das neue Storyboard verschoben wurden und nicht außerhalb davon referenziert wurden (wie es sein sollte), deren Referenzen aus main.storyboard löschen sollten (entspannen Sie sich, sie bleiben im neu erstellten Storyboard, Sie sind es) nur Verweise auf sie löschen).

9
hris.to

In den Apple-Dokumenten heißt es, dass Sie möglicherweise mehrere Storyboards haben. Leider gehen sie nicht ins Detail, wie das geht. Wie Sie herausgefunden haben, hilft Ihnen Interface Builder nicht weiter. Sie müssen dies also im Code tun. Es funktioniert ähnlich wie das Laden von XIBs:

[UIStoryboard storyboardWithName:@”MyNewStoryboard” bundle:myBundle]

Wenn Sie jedoch nicht "ein großes/aufgeblähtes Storyboard" möchten, wie Sie in Ihrem Kommentar gesagt haben, sind XIBs der richtige Weg. Diese „Größe“ ist der Vorteil: Alle Übergänge zwischen VCs sind an einer Stelle angeordnet. Wenn Sie über mehrere Storyboards verfügen, können Sie mehrere unterschiedliche und nicht miteinander verknüpfte Abläufe in Ihrer App unterstützen: z. B. ein Storyboard für einen komplexen Konfigurationsablauf und ein anderes für den Hauptbenutzerablauf.

7
Tim

Ich habe festgestellt, dass Sie, wenn Sie in einem zweiten Storyboard einen benannten Segue haben, den Sie in einem Aufruf zum Ausführen von SegueWithIdenitfier verwenden möchten, das Feld "Storyboard-ID" auf der Registerkarte "Identität" im Quell-ViewController festlegen müssen.

Wenn Sie beispielsweise einen VC mit dem Namen "ViewController1" und einem anderen VC mit dem Namen "segue1" angegeben haben, setzen Sie die "Storyboard-ID" von "ViewController1" auf einen beliebigen Wert (sagen Sie "viewC1" oder so etwas) ) und dann können Sie in ViewController1.m [self performSegueWithIdentifier: @ "segue1" sender: self] verwenden.

2
nh32rg

Xcode 8.2.1

Sie können auf einen View Controller in einem externen Storyboard verweisen.

relationship from TabBarController to Storyboard Reference

ziehen Sie eine Verbindung von UITabBarController in die externe Storyboard-Referenz, und fügen Sie sie als Beziehung "View Controller" hinzu. Im Hauptstoryboard wird "Item/square" angezeigt, aber im externen Storyboard sollten Sie ein UITabBarItem hinzufügen und den Namen und die Bilder für die Registerkarte definieren.

enter image description here

Attributes Inspector, wenn das Storyboard Reference ist ausgewählt.

Sie müssen dem externen Controller außerdem eine "Storyboard-ID" in seinem Storyboard geben (hier nicht gezeigt), und Referenz ist der Name in der Referenz.

2
bshirley

Führen Sie die folgenden Schritte aus, um diese Aufgabe zu erfüllen:

Schritt 1 : Suche nach einem Storyboard Reference in Komponenten (siehe Screenshot)

Schritt 2 : Wählen Sie eine neue Storyboard-Referenz. (Siehe Screenshot)

Schritt 3 : Geben Sie den neuen Storyboard-Namen und die Kennung der Kennung des ursprünglichen View-Controllers ein (siehe Screenshot).

enter image description here

Erstellen und ausführen. Es wird funktionieren.

1
Dheeraj D