web-dev-qa-db-fra.com

Contrôleur de barre d'onglets à l'intérieur d'un contrôleur de navigation ou partage d'une vue racine de navigation

J'essaie d'implémenter une interface utilisateur structurée comme dans l'application Tweetie , qui se comporte comme suit: le contrôleur de vue de niveau supérieur semble être un contrôleur de navigation , dont la vue racine est une vue de table "Comptes". Si vous cliquez sur un compte, il passe au deuxième niveau, qui a une barre d'onglets en bas. Chaque élément d'onglet affiche une liste différente et vous permet d'explorer davantage (les niveaux suivants ne montrent pas la barre d'onglets).

Il semble donc que la hiérarchie de mise en œuvre soit:

  • UINavigationController
    1. Comptes : UITableViewController
    2. UITabBarController
      1. Tweets : UITableViewController
        • Vue détaillée d'un Tweet/utilisateur/etc
      2. Réponses : UITableViewController
      3. ...

Cela semble fonctionner [^ 1], mais semble ne pas être pris en charge selon la documentation du SDK pour -pushViewController:animated: (non souligné dans l'original):

viewController : Le contrôleur de vue qui est poussé sur la pile. Il ne peut pas s'agir d'une instance de contrôleur de barre d'onglets.

Je voudrais éviter les API privées et autres, mais je ne sais pas pourquoi cette utilisation est explicitement interdite même si cela semble fonctionner correctement. Quelqu'un connaît la raison?

J'ai pensé à mettre le contrôleur de la barre d'onglets en tant que contrôleur principal, chacun des onglets contenant des contrôleurs de navigation distincts. Le problème avec cela est que chaque contrôleur de navigation doit partager un seul contrôleur de vue racine (à savoir le tableau "Comptes" dans Tweetie ) - cela ne fonctionne pas ' t semble fonctionner: pousser le contrôleur de table vers un second contrôleur de navigation semble le retirer du premier. Sans parler de toute la tenue de livres lors de la sélection d'un compte différent serait probablement une douleur.

Comment dois-je mettre cela en œuvre de la bonne façon?

[^ 1]: le contrôleur de barre d'onglets doit être sous-classé afin que l'élément de navigation du contrôleur de barre d'onglets à ce niveau reste synchronisé avec l'élément de navigation de l'onglet sélectionné, et que le contrôleur de table de l'onglet individuel doive pousser leurs vues de détail respectives vers self.tabBarController.navigationController au lieu de self.navigationController.

79
Daniel Dickison

Les deux réponses précédentes avaient raison - je n'utilise pas UITabBarController dans Tweetie. Il est assez facile d'écrire un XXTabBarController personnalisé (sous-classe ordinaire de UIViewController) qui est heureux d'être poussé sur une pile de contrôleurs de navigation, mais qui vit toujours selon la philosophie du "view controller". Chaque "onglet" de la vue spécifique au compte (Tweets/Replies/Messages) est son propre contrôleur de vue, et en ce qui les concerne, ils sont échangés autour de l'écran par un plain-ol UITabBarController.

63
Loren

Je crée une application qui utilise un cadre de navigation similaire à Tweetie. J'ai écrit un article sur la façon de le faire sur mon blog www.wiredbob.com qui renvoie également au code source. C'est un modèle complet que vous pouvez prendre et utiliser comme base pour un autre projet. Bonne chance!

34
Robert Conn

Il est possible d'ajouter un UITabBar à n'importe quel UIViewController. De cette façon, vous n'avez pas besoin de pousser un UITabBarController et donc de respecter les directives de l'API Apple.

Dans le générateur d'interface, UITabBar se trouve sous "Windows, vues et barres" dans la bibliothèque Cocoa Touch.

10
Himadri Choudhury

Je le fais dans quelques-unes de mes applications. L'astuce pour ajouter une barre d'onglets à une application basée sur navigationController est de NE PAS utiliser un TabBarController. Ajoutez une barre d'onglets à la vue, faites du contrôleur de vue pour cette vue un TabBarDelegate et répondez aux sélections de l'utilisateur sur la barre d'onglets dans le code du contrôleur de vue.

J'utilise des barres d'onglets pour ajouter des vues supplémentaires à la vue de la barre d'onglets en tant que sous-vues, pour recharger une vue de table avec différents jeux de données, pour recharger une UIPickerView, etc.

9
Alpinista

Je luttais depuis une heure pour implémenter un UITabBar car il se masquait lorsque j'essayais d'afficher ma vue; alors j'ai trouvé ceci post :

Fondamentalement, assurez-vous d'insérer votre nouvelle vue sous la barre d'onglets, par cette ligne de code:

[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];
6
esilver

C'est comme ça que je l'ai fait. Cela pousse en fait un tabbarcontroller sur le contrôleur de navigation. Ça fonctionne bien. Je n'ai trouvé nulle part dans la documentation que Apple ne prend pas en charge cette méthode. Quelqu'un peut-il me donner un lien vers cet avertissement?

Si c'est la vérité, est-il possible que Apple refuse de publier mon application sur l'appstore?

-(void)setArrayAndPushNextController
{
    MyFirstViewController *myFirstViewController = [[MyFirstViewController alloc] init];
    MySecondViewController *mySecondViewController = [[MySecondViewController alloc] init];

    myFirstViewController.array = self.array;


    NSArray *array = [[NSArray alloc] initWithObjects:myFirstViewController, mySecondViewController, nil];
    UITabBarController *tab = [[UITabBarController alloc] init];
    tab.viewControllers = array;

    [array release];

    UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"first title" image:nil tag:1];
    UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"second title" image:nil tag:2];

    myFirstViewController.tabBarItem = item1;
    mySecondViewController.tabBarItem = item2;

    [self stopAnimatingSpinner];

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

    [tab release];
    [item1 release];
    [item2 release];
}
3
savudin

Dans mon application, le contrôleur de vue racine est un contrôleur UINavigation. À un certain moment de l'application, je dois afficher un UITabBar. J'ai essayé d'implémenter un UITabBar sur un UIView dans la hiérarchie de navigation, comme certains des messages précédents l'ont suggéré, et cela fonctionne. Mais j'ai trouvé que je voulais plus du comportement par défaut fourni par le contrôleur d'onglets et j'ai trouvé un moyen d'utiliser UITabBarController avec le contrôleur UINavigation:

1) Lorsque je veux afficher la vue UITabBarController, je fais ceci:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = myUiTabBarControllerInstance;

2) Lorsque je veux revenir à l'endroit où j'étais dans la hiérarchie de navigation, je fais ceci:

appDelegate.window.rootViewController = myNavControllerInstance;
3
richardsun

Cela pourrait être réalisé en incorporant simplement le TabBarController dans le contrôleur de navigation. Dans le storyboard:

  1. Faites glisser un ViewController
  2. Cliquez sur la scène de ViewController
  3. Cliquez sur l'éditeur >> Intégrer dans >> Contrôleur de navigation.
  4. Faites glisser un bouton sur le même ViewController.
  5. Faites glisser un TabBarController
  6. Connectez le bouton du ViewController au TabBarController via Push Segue Action.

Dans ce cas, seul le RootViewController de TabBarController serait dans la pile du contrôleur de navigation. Tous les TabBarItems auraient la barre de navigation en haut et l'utilisateur peut aller à l'écran d'accueil à tout moment, quel que soit le TabBarItem sélectionné

Cela peut être fait sur n'importe quel ViewController de la pile du contrôleur de navigation.

Si cela fonctionne, veuillez me suggérer comment augmenter la réputation afin que je puisse poster les images et le code dans la réponse suivante. :)

2
caffieneToCode

J'ai écrit un article de blog sur la façon dont j'ai abordé ce problème. Pour moi, utiliser une vue modale était une solution plus simple que d'écrire une implémentation de barre d'onglets personnalisée.

http://www.alexmedearis.com/uitabbarcontroller-inside-a-uinavigationcontroller/

1
Alex Medearis