Passer à un onglet TabBar par programme?

159

Disons que j'ai une vue UIButtondans un onglet dans mon application iPhone et que je souhaite qu'elle ouvre un autre onglet dans la barre d'onglets de TabBarController. Comment écrire le code pour faire cela?

Je suppose que je décharge la vue existante et charge une vue d'onglet spécifique, mais je ne sais pas comment écrire le code exactement.

appareil photo
la source
J'ai des problèmes avec les méthodes ci-dessus, les gars m'aident dans ma [question] [1] [1]: stackoverflow.com/questions/19742416/…
Roman Simenok

Réponses:

399

Essayez ce code en Swift ou Objective-C

Rapide

self.tabBarController.selectedIndex = 1

Objectif c

[self.tabBarController setSelectedIndex:1];
Jordan
la source
8
Notez que si l'index correspond à un onglet dans le contrôleur d'affichage Plus (si vous avez plus de cinq onglets), cela ne fonctionnera pas. Dans ce cas, utilisez -setSelectedViewController:.
Joe D'Andrea
Après avoir fait cela et que les onglets ont été modifiés avec succès, je ne peux plus sélectionner la barre d'onglets normalement. MISE À JOUR: c'était en quelque sorte lié au fait que j'appelais popToRootViewController juste avant d'échanger les onglets par programme.
Adam Johns
Mais comment Self ne fonctionnera pas si je veux changer l'onglet. disons que je clique sur l'onglet 3 et affiche alertView maintenant lorsque l'utilisateur appuie sur ok, je veux basculer à nouveau vers l'onglet 1. Le moi n'aura pas raison car ce n'est pas l'objet actuel. Correct ?
Alix
Cela fonctionne bien mais je dois aussi transmettre les données tout en changeant d'onglet. J'ai une étiquette dans l'onglet où je passe qui doit être mise à jour dès que je change d'onglet.! Une solution simple à cela?
Md Rais
@AdamJohns Comment avez-vous réussi à résoudre votre problème. pour le faire se comporter comme tabBar natif. il devrait apparaître sur rootViewController au deuxième clic.
Waqas
20

Notez que les onglets sont indexés à partir de 0. Ainsi, l'extrait de code suivant fonctionne

tabBarController = [[UITabBarController alloc] init];
.
.
.
tabBarController.selectedViewController = [tabBarController.viewControllers objectAtIndex:4];

va au cinquième onglet de la barre.

John Smith
la source
12

Mon avis est que l' selectedIndexutilisation objectAtIndexn'est pas forcément la meilleure façon de changer d'onglet. Si vous réorganisez vos onglets, une sélection d'index codée en dur peut perturber le comportement de votre ancienne application.

Si vous disposez de la référence d'objet du contrôleur de vue vers lequel vous souhaitez basculer, vous pouvez faire:

tabBarController.selectedViewController = myViewController

Bien sûr, vous devez vous assurer que c'est myViewControllervraiment dans la liste des tabBarController.viewControllers.

ThomasT
la source
J'avais besoin de sélectionner plusNavController et c'est le seul moyen de le faire pour autant que je sache
Ossir
9

Vous pouvez simplement définir la selectedIndexpropriété sur UITabBarController sur l'index approprié et la vue sera modifiée tout comme l'utilisateur a appuyé sur le bouton de l'onglet.

Alex Deem
la source
6
La seule petite différence étant que la méthode de délégué qui peut informer l'utilisateur de changer d'onglet n'est pas appelée.
Brad The App Guy
3
Le réglage selectedIndexne fonctionne pas non plus pour moi avec des index> 4, mais le selectedViewControllerfait.
bugloaf
3

J'ai essayé ce que Disco S2 suggérait, c'était proche mais c'est ce qui a fini par marcher pour moi. Cela a été appelé après avoir terminé une action dans un autre onglet.

for (UINavigationController *controller in self.tabBarController.viewControllers)
{
    if ([controller isKindOfClass:[MyViewController class]])
    {
        [self.tabBarController setSelectedViewController:controller];
        break;
    }
}
Joped
la source
2

Pour les cas où vous pouvez déplacer les onglets, voici du code.

for ( UINavigationController *controller in self.tabBarController.viewControllers ) {
            if ( [[controller.childViewControllers objectAtIndex:0] isKindOfClass:[MyViewController class]]) {
                [self.tabBarController setSelectedViewController:controller];
                break;
            }
        }
StuStirling
la source
2

Comme la solution de Stuart Clark mais pour Swift 3:

func setTab<T>(_ myClass: T.Type) {
    var i: Int = 0
    if let controllers = self.tabBarController?.viewControllers {
        for controller in controllers {
            if let nav = controller as? UINavigationController, nav.topViewController is T {
                break
            }
            i = i+1
        }
    }
    self.tabBarController?.selectedIndex = i
}

Utilisez-le comme ceci:

setTab(MyViewController.self)

Veuillez noter que mon tabController est lié à viewControllers derrière navigationControllers. Sans navigationControllers, cela ressemblerait à ceci:

if let controller is T {
Json
la source
Sans boucle, pas de contrôleurs de navigation: func selectViewController <ViewControllerModel> (type: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers? .First (où: {viewController in viewController est ViewControllerModel})}
dev_exo
1

Je voulais être en mesure de spécifier quel onglet était affiché par classe plutôt que par index car je pensais que cela constituait une solution robuste qui dépendait moins de la façon dont vous connectez IB. Je n'ai pas trouvé les solutions de Disco ou de Joped pour fonctionner, j'ai donc créé cette méthode:

-(void)setTab:(Class)class{
    int i = 0;
    for (UINavigationController *controller in self.tabBarContontroller.viewControllers){
        if ([controller isKindOfClass:class]){
            break;
        }
        i++;
    }
    self.tabBarContontroller.selectedIndex = i;
}

vous l'appelez comme ceci:

[self setTab:[YourClass class]];

J'espère que cela est utile à quelqu'un

Stuart Clark
la source
Cela a très bien fonctionné! Je l'ai réécrit pour Swift3 dans une autre réponse.
Json
1

Mon problème est un peu différent, je dois passer d'un childViewController dans le 1er tabBar à home viewController du 2nd tabBar. J'utilise simplement la solution fournie à l'étage:

tabBarController.selectedIndex = 2

Cependant, lorsqu'il est passé à la page d'accueil du 2nd tabBar, le contenu est invisible. Et quand je débogue, viewDidAppear, viewWillAppear, viewDidLoad, aucun d'entre eux n'est appelé. Mes solutions consistent à ajouter le code suivant dans UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}
Jin
la source
0

Utilisation dans le AppDelegate.mfichier:

(void)tabBarController:(UITabBarController *)tabBarController
 didSelectViewController:(UIViewController *)viewController
{

     NSLog(@"Selected index: %d", tabBarController.selectedIndex);

    if (viewController == tabBarController.moreNavigationController)
    {
        tabBarController.moreNavigationController.delegate = self;
    }

    NSUInteger selectedIndex = tabBarController.selectedIndex;

    switch (selectedIndex) {

        case 0:
            NSLog(@"click me %u",self.tabBarController.selectedIndex);
            break;
        case 1:
            NSLog(@"click me again!! %u",self.tabBarController.selectedIndex);
            break;

        default:
            break;

    }

}
Rakesh Singh
la source
0

Comme la solution de Stuart Clark mais pour Swift 3 et en utilisant l'identifiant de restauration pour trouver l'onglet correct:

private func setTabById(id: String) {
  var i: Int = 0
  if let controllers = self.tabBarController?.viewControllers {
    for controller in controllers {
      if let nav = controller as? UINavigationController, nav.topViewController?.restorationIdentifier == id {
        break
      }
      i = i+1
    }
  }
  self.tabBarController?.selectedIndex = i
}

Utilisez-le comme ceci ("Humans" et "Robots" doivent également être définis dans le storyboard pour un viewController spécifique et son ID de restauration, ou utilisez l'ID du storyboard et cochez "utiliser l'ID du storyboard" comme ID de restauration):

struct Tabs {
    static let Humans = "Humans"
    static let Robots = "Robots"
}
setTabById(id: Tabs.Robots)

Veuillez noter que mon tabController est lié à viewControllers derrière navigationControllers. Sans navigationControllers, cela ressemblerait à ceci:

if controller.restorationIdentifier == id {
Json
la source
0
import UIKit

class TabbarViewController: UITabBarController,UITabBarControllerDelegate {

//MARK:- View Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

//Tabbar delegate method
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController
    yourView.popToRootViewController(animated:false)
}



}
Davender Verma
la source
1
Habituellement, il est préférable d'expliquer une solution au lieu de simplement publier quelques lignes de code anonyme. Vous pouvez lire Comment écrire une bonne réponse , et aussi expliquer des réponses entièrement basées sur le code
Anh Pham