Mudando para uma exibição da guia TabBar programaticamente?


159

Digamos que eu tenha uma UIButtonvisualização em uma guia no meu aplicativo para iPhone e quero que ela abra uma guia diferente na barra de guias do TabBarController. Como eu escreveria o código para fazer isso?

Estou assumindo que descarrego a exibição existente e carrego uma exibição de guia específica, mas não sei como escrever o código exatamente.


Tenho problemas com métodos acima, caras de ajuda no meu [pergunta] [1] [1]: stackoverflow.com/questions/19742416/...
Roman Simenok

Respostas:


399

Experimente este código em Swift ou Objective-C

Rápido

self.tabBarController.selectedIndex = 1

Objetivo-C

[self.tabBarController setSelectedIndex:1];

8
Observe que, se o índice for mapeado para uma guia no controlador de exibição Mais (se você tiver mais de cinco guias), isso não funcionará. Nesse caso, use -setSelectedViewController:.
Joe D'Andrea

Depois de fazer isso e alterar as guias com êxito, não posso mais selecionar a barra de guias normalmente. UPDATE: de alguma forma, isso me chamou de popToRootViewController antes de eu trocar de guia programaticamente.
Adam Johns

Mas como o Self não funcionará se eu quiser mudar a guia. digamos que eu clique na guia 3 e mostre o alertView agora quando o usuário pressionar ok, desejo mudar para a guia 1 novamente. O eu não estará certo, pois não é o objeto atual. Correto?
Alix

Isso funciona bem, mas eu também tenho que passar os dados enquanto alterno as guias. Eu tenho um rótulo na guia onde eu mudo para que precisa ser atualizado assim que eu mudar a guia.! Alguma solução fácil para isso?
Md Ra

@AdamJohns Como você conseguiu resolver seu problema. para se comportar como tabBar nativo. ele deve aparecer no rootViewController no segundo clique.
Waqas

20

Observe que as guias são indexadas a partir de 0. Portanto, o seguinte snippet de código funciona

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

vai para a quinta aba no bar.


12

Minha opinião é que selectedIndexou usar objectAtIndexnão é necessariamente a melhor maneira de mudar a guia. Se você reordenar suas guias, uma seleção de índice codificado pode interferir no comportamento anterior do aplicativo.

Se você tiver a referência de objeto do controlador de exibição para a qual deseja alternar, poderá:

tabBarController.selectedViewController = myViewController

Claro que você deve ter certeza de que myViewControllerrealmente está na lista de tabBarController.viewControllers.


Eu precisava para selecionar moreNavController e é a única maneira de fazer isso, tanto quanto eu sei
Ossir

9

Você pode simplesmente definir a selectedIndexpropriedade no UITabBarController para o índice apropriado e a exibição será alterada assim como o usuário tocou no botão tab.


6
Com a pequena diferença, o método delegado que pode informar as guias de alternância do usuário não é chamado.
Brad The App Guy

3
Definir selectedIndextambém não funciona para mim com índices> 4, mas selectedViewControllerfunciona.
bugloaf

3

Eu tentei o que o Disco S2 sugeriu, estava próximo, mas foi o que acabou funcionando para mim. Isso foi chamado após a conclusão de uma ação dentro de outra guia.

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

2

Para os casos em que você pode mover as guias, aqui está um código.

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

2

Como a solução de Stuart Clark, mas para 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
}

Use-o assim:

setTab(MyViewController.self)

Observe que meu tabController está vinculado a viewControllers atrás de navigationControllers. Sem navigationControllers, ficaria assim:

if let controller is T {

Sem loop, nenhum controlador de navegação: func selectViewController <ViewControllerModel> (tipo: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers? .First (onde: {viewController no viewController é ViewControllerModel})}
dev_exo

1

Queria poder especificar qual guia foi mostrada por classe, em vez de indexar, pois achei que era uma solução robusta e menos dependente de como você conecta o IB. Não encontrei as soluções da Disco ou da Joped para funcionar, então criei este método:

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

você chama assim:

[self setTab:[YourClass class]];

Espero que isto ajude alguém


Isso funcionou muito bem! Reescrevi para o Swift3 em outra resposta.
Json 15/05

1

Meu problema é um pouco diferente. Preciso mudar de um childViewController no 1º tabBar para o home viewController do 2º tabBar. Simplesmente uso a solução fornecida no andar de cima:

tabBarController.selectedIndex = 2

No entanto, quando alternou para a página inicial da 2ª guiaBar, o conteúdo fica invisível. E quando depuro, viewDidAppear, viewWillAppear, viewDidLoad, nenhum deles é chamado. Minhas soluções é adicionar o seguinte código no UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

0

Use no AppDelegate.marquivo:

(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

Como a solução de Stuart Clark, mas para Swift 3 e usando o identificador de restauração para encontrar a guia correta:

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
}

Use-o assim ("Humanos" e "Robôs" também devem ser definidos no storyboard para um viewController específico e seu ID de restauração, ou use o Storyboard ID e marque "use storyboard ID" como ID de restauração):

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

Observe que meu tabController está vinculado a viewControllers atrás de navigationControllers. Sem navigationControllers, ficaria assim:

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
Geralmente, é melhor explicar uma solução em vez de apenas postar algumas linhas de código anônimo. Você pode ler Como redigir uma boa resposta e também Explicar respostas inteiramente baseadas em código
Anh Pham
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.