Passare a una visualizzazione della scheda TabBar a livello di codice?


159

Diciamo che ho una vista UIButtonin una scheda nella mia app per iPhone e voglio che abbia una scheda diversa nella barra delle schede di TabBarController. Come scriverei il codice per fare questo?

Suppongo di scaricare la vista esistente e caricare una vista a schede specifica, ma non sono sicuro di come scrivere esattamente il codice.


Ho problemi con i metodi di cui sopra, i ragazzi di aiuto nel mio [domanda] [1] [1]: stackoverflow.com/questions/19742416/...
romana Simenok

Risposte:


399

Prova questo codice in Swift o Objective-C

veloce

self.tabBarController.selectedIndex = 1

Objective-C

[self.tabBarController setSelectedIndex:1];

8
Si noti che, se l'indice è associato a una scheda all'interno del controller della vista Altro (se si hanno più di cinque schede), ciò non funzionerà. In tal caso, utilizzare -setSelectedViewController:.
Joe D'Andrea

Dopo averlo fatto e dopo aver modificato correttamente le schede, non riesco più a selezionare normalmente la barra delle schede. AGGIORNAMENTO: questo è stato in qualche modo correlato al fatto che ho chiamato popToRootViewController proprio prima di scambiare le schede a livello di codice.
Adam Johns,

Ma come non funzionerò se voglio cambiare scheda. diciamo che faccio clic sulla scheda 3 e visualizzo alertView ora mentre l'utente preme ok, voglio passare nuovamente alla scheda 1. Il Sé non avrà ragione in quanto non è l'oggetto corrente. Corretta ?
Alix,

Funziona bene, ma devo anche passare i dati mentre si cambia scheda. Ho un'etichetta nella scheda in cui passo a quella che deve essere aggiornata non appena cambio la scheda.! Qualche soluzione semplice a questo?
Md Rais,

@AdamJohns Come sei riuscito a risolvere il tuo problema. per farlo funzionare come tabBar nativo. dovrebbe apparire su rootViewController al secondo clic.
Waqas,

20

Nota che le schede sono indicizzate a partire da 0. Quindi il seguente frammento di codice funziona

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

va alla quinta scheda nella barra.


12

La mia opinione è che selectedIndexo usare objectAtIndexnon è necessariamente il modo migliore per cambiare scheda. Se riordini le tue schede, una selezione di indice codificata potrebbe compromettere il comportamento della tua app precedente.

Se si dispone del riferimento all'oggetto del controller di visualizzazione a cui si desidera passare, è possibile:

tabBarController.selectedViewController = myViewController

Ovviamente devi assicurarti che sia myViewControllerdavvero nella lista di tabBarController.viewControllers.


Avevo bisogno di selezionare moreNavController ed è l'unico modo per farlo per quanto ne so
Ossir

9

Puoi semplicemente impostare la selectedIndexproprietà su UITabBarController sull'indice appropriato e la vista verrà modificata proprio come l'utente ha toccato il pulsante della scheda.


6
Con l'unica piccola differenza che non viene chiamato il metodo delegato in grado di informare sulle schede di commutazione dell'utente.
Brad The App Guy,

3
Anche l'impostazione selectedIndexnon funziona per me con indici> 4, ma selectedViewControllerfunziona.
bugloaf

3

Ho provato ciò che Disco S2 ha suggerito, era vicino ma questo è quello che ha finito per funzionare per me. Questo è stato chiamato dopo aver completato un'azione all'interno di un'altra scheda.

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

2

Per i casi in cui potresti spostare le schede, ecco un po 'di codice.

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

2

Come la soluzione di Stuart Clark ma per 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
}

Usalo in questo modo:

setTab(MyViewController.self)

Nota che il mio tabController si collega a viewController dietro navigationController. Senza navigationController sarebbe simile a questo:

if let controller is T {

Senza looping, nessun controller di navigazione: func selectViewController <ViewControllerModel> (tipo: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers? .First (dove: {viewController in viewController è ViewControllerModel})}
dev_exo

1

Volevo essere in grado di specificare quale scheda veniva mostrata per classe piuttosto che come indice, poiché pensavo che fosse una soluzione solida che dipendeva meno da come si collegava IB. Non ho trovato le soluzioni di Disco o Joped per funzionare, quindi ho creato questo metodo:

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

lo chiami così:

[self setTab:[YourClass class]];

Spero che questo sia utile a qualcuno


Questo ha funzionato alla grande! L'ho riscritto per Swift3 in un'altra risposta.
Json,

1

Il mio problema è un po 'diverso, ho bisogno di passare da un figlio ViewController in 1a tabBar a home viewController di 2a tabBar. Uso semplicemente la soluzione fornita al piano superiore:

tabBarController.selectedIndex = 2

Tuttavia, quando si passa alla home page della 2a tabbar, il contenuto è invisibile. E quando eseguo il debug, viewDidAppear, viewWillAppear, viewDidLoad, nessuno di questi viene chiamato. Le mie soluzioni sono aggiungere il seguente codice in UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

0

Utilizzare nel AppDelegate.mfile:

(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;

    }

}

0

Come la soluzione di Stuart Clark ma per Swift 3 e l'utilizzo dell'identificatore di restauro per trovare la scheda corretta:

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
}

Usalo in questo modo ("Humans" e "Robots" devono anche essere impostati nello storyboard per viewController specifico e il suo ID di ripristino, oppure usa lo Storyboard ID e seleziona "usa lo storyboard ID" come ID di ripristino):

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

Nota che il mio tabController si collega a viewController dietro navigationController. Senza navigationController sarebbe simile a questo:

if controller.restorationIdentifier == id {

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)
}



}

1
Di solito è meglio spiegare una soluzione invece di pubblicare solo alcune righe di codice anonimo. Puoi leggere Come posso scrivere una buona risposta , e anche Spiegare risposte interamente basate sul codice
Anh Pham,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.