web-dev-qa-db-fra.com

Utilisation de plusieurs scénarimages dans iOS

Mon objectif est de créer une application à onglets, puis la vue de chacun des onglets est construite dans des storyboards séparés.

Storyboard screenshot

Mon tableau principal est une vue par onglet.

Ensuite, je crée un storyboard secondaire (storyboard n ° 2) avec 2 contrôleurs de vue. Le premier contrôleur de vue (également coché comme initial) a un bouton et passe au second point. First view controller

J'ai réussi à charger la vue en sous-classant et en surchargeant loadView à partir du storyboard n ° 2. loadView override

Voici la sortie du simulateur.

Simulator

Lorsque je clique sur le bouton "click me", je reçois un EXC_BAD_ACCESS. La transition ne fonctionne pas, semble que le deuxième scénario n'est pas chargé complètement.

Quelqu'un a-t-il déjà essayé de le faire et le faire fonctionner? Il y a une vidéo sur youtube de SkillMaster.net mais il ne montre pas si un segue travaille sous le storyboard secondaire. la vidéo est ici: http://youtu.be/D4_twoYvB4M

Merci pour toute contribution et aide!

Captures d'écran:

74

Ce sont les meilleurs articles que j'ai vus sur plusieurs storyboards.

Non seulement ce gars vous dit comment créer un nouveau scénario en code, il

  • recommande plusieurs story-boards en pratique (code plus modulaire)
  • explique quand utiliser xibs par rapport aux storyboards (les xibs conservent des vues, les storboards sont basés sur des contrôleurs)
  • fournit une classe pour relier les storyboards avec des légendes sur github

Notez que ce dernier point est important car le principal inconvénient de plusieurs story-boards est qu’il est généralement impossible de les lier avec des séquences,

Voir aussi la discussion ici

79
Rhubarb

Le PO a modifié sa question pour y inclure la réponse:

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

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

Bien sûr, l’appel d’origine est significatif, car vous pourriez avoir 2 storyboards et leur pile de vues en mémoire. Il est donc probablement préférable que vous appeliez ce code de l'extérieur des contrôleurs de vue de l'autre storyboard.

44
pchap10k

J'ai examiné l'approche RBStoryboardLink proposée par Rhubarb. Cette implémentation remplace les propriétés du contrôleur de vue, ce qui semble étrange. Je crois avoir trouvé le moyen d'éviter cela. Voici le projet de démonstration .

Contrôleurs de navigation

Les contrôleurs de navigation pourraient simplement définir un contrôleur de vue référencé en tant que racine. L'implémentation d'un tel contrôleur de vue peut ressembler à ceci:

@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

Contrôleurs de vue

Les problèmes commencent lorsque vous souhaitez pousser un contrôleur de vue défini dans un storyboard externe. C'est le cas lorsque les propriétés sont copiées. Au lieu de cela, nous pouvons implémenter une séquence personnalisée qui remplacera un contrôleur de destination factice par un contrôleur réel provenant du storyboard externe.

@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 est utilisé comme espace réservé et contient les propriétés requises pour les propriétés de substitution (storyboardName et sceneIdentifier).

@interface ExternViewController : UIViewController

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

@end

@implementation ExternViewController

@end

Nous devons définir ces propriétés et la classe personnalisée pour le contrôleur de vue d'espace réservé. Et aussi relier le contrôleur de vue avec ExternStoryboardSegue.

IB screenshot

19
vokilam

Depuis l'un de mes fichiers XIB, je navigue dans une partie plus compliquée de l'interface graphique et j'utilise un Storyboard pour cette partie. Donc, un bouton de mon XIB ira au storyboard. Le code que j'ai pour cela est:

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

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

Cela réussira à pousser mon StoryBoard sur la vue. Le code ci-dessus est appelé à partir d’une action "Retoucher l’intérieur".

16
Joachim H. Skeie

À partir de Xcode 7 (et ramené sur iOS8), vous pouvez désormais avoir des références de storyboard. Cela a été mentionné dans cette WWDC 2015 (il commence à en parler vers la première heure). En gros, tout ce que vous avez à faire est de sélectionner ViewController que vous souhaitez déplacer dans un storyboard séparé, puis de cliquer sur Editeur-> Refactoriser en Storyboard .... Donnez-lui un nom et le tour est joué:

enter image description here

Veuillez noter que si vous avez des VC déplacés vers le nouveau storyboard et qu’ils ne sont pas référencés en dehors de celui-ci (ce qu’il devrait être), vous devez supprimer leurs références de main.storyboard (détendez-vous, ils resteront dans le storyboard nouvellement créé). supprimer uniquement les références à celles-ci).

9
hris.to

La documentation d'Apple dit que vous pouvez avoir plusieurs story-boards. Malheureusement, ils n'entrent pas dans les détails pour savoir comment faire cela. Comme vous l'avez découvert, Interface Builder ne vous aidera pas, vous devrez donc le faire en code. Cela fonctionne beaucoup comme charger des XIBs:

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

Cela dit, si vous ne "voulez pas un grand storyboard gonflé", comme vous l'avez dit dans votre commentaire, les XIB sont vraiment la voie à suivre. Cette "grandeur" est l’avantage: toutes les transitions entre les VC sont placées au même endroit. Avoir plusieurs story-boards, c'est vraiment pouvoir prendre en charge plusieurs flux différents et non liés dans votre application: par exemple, un story-board pour un flux de configuration complexe et un autre pour le flux d'utilisateur principal.

7
Tim

J'ai constaté que, si vous avez une séquence nommée dans un deuxième storyboard, que vous souhaitez utiliser dans un appel à performSegueWithIdenitfier: vous devez définir le champ "Storyboard ID" dans l'onglet "Identity" du ViewController source.

Par exemple, si vous donnez un VC appelé "ViewController1" avec une séquence appelée "segue1" à un autre VC, définissez le "Storyboard ID" de "ViewController1" sur quelque chose (par exemple "viewC1" ) puis dans ViewController1.m vous pouvez utiliser [self performSegueWithIdentifier: @ "segue1" sender: self].

2
nh32rg

Xcode 8.2.1

Vous pouvez référencer un contrôleur de vue dans un storyboard externe.

relationship from TabBarController to Storyboard Reference

faites glisser une connexion de UITabBarController vers la référence de storyboard externe, ajoutez-la en tant que relation "Contrôleurs de vue". Dans le storyboard principal, il est indiqué par "Item/square", mais dans le storyboard externe, vous devez ajouter un UITabBarItem et définir le nom et les images pour l'onglet.

enter image description here

Inspecteur d'attributs lorsque le Storyboard Reference est sélectionné.

Vous devrez également attribuer au contrôleur externe un "ID de storyboard" dans son storyboard (non affiché ici), et référence son nom dans la référence.

2
bshirley

Suivez les étapes ci-dessous pour réaliser cette tâche:

Étape 1 : recherchez un Storyboard Reference en composants (voir capture d'écran)

Étape 2 : sélectionnez une nouvelle référence de scénario. (Voir la capture d'écran)

Étape 3 : indiquez le nouveau nom du storyboard et l'identifiant de l'identifiant du contrôleur de vue initial (voir la capture d'écran).

enter image description here

Construire et exécuter. Cela fonctionnera.

1
Dheeraj D