Controlador de barra de tabulação dentro de um controlador de navegação ou partilha de uma vista de raiz de navegação

Estou tentando implementar uma interface do usuário estruturada como no aplicativo Tweetie , que se comporta assim: o controlador de visualização de nível superior parece ser um controlador de navegação, cuja visualização raiz é uma visualização de tabela “Contas”. Se você clicar em qualquer conta, ela vai para o segundo nível, que tem uma barra de guias na parte inferior. Cada item da guia mostra uma lista diferente e permite que você faça uma pesquisa mais detalhada (os níveis subseqüentes não mostram a barra de guias).

Então, isso parece que a hierarquia de implementação é:

  • UINavigationController
    1. Contas : UITableViewController
    2. UITabBarController
      1. Tweets : UITableViewController
        • Visualização de detalhes de um tweet / usuário / etc
      2. Respostas : UITableViewController

Isso parece funcionar [^ 1], mas parece não ser suportado de acordo com a documentação do SDK para -pushViewController:animated: (emphasis added):

viewController : O controlador de exibição que é colocado na pilha. Não pode ser uma instância do controlador da barra de guias.

Eu gostaria de evitar APIs privadas e coisas do tipo, mas não sei por que esse uso é explicitamente proibido, mesmo quando parece funcionar bem. Alguém sabe o motivo?

Pensei em colocar o controlador da barra de guias como o controlador principal, com cada uma das guias contendo controladores de navegação separados. O problema com isto é que cada controlador de nav precisa compartilhar um único controlador de visão de raiz (ou seja, a tabela “Contas” no Tweetie ) – isso não parece funcionar: empurrar o controlador de tabela para um segundo controlador de navegação parece removê-lo desde o primeiro. Sem mencionar que toda a contabilidade ao selecionar uma conta diferente provavelmente seria uma dor.

Como devo implementar isso do jeito certo?

[^ 1]: O controlador da barra de guias precisa ser subclassificado para que o item de navegação do controlador da barra de tabulação permaneça sincronizado com o item de navegação da guia selecionada e a necessidade do controlador de tabela individual de empurrar suas respectivas vistas de detalhe para self.tabBarController.navigationController vez de self.navigationController .

As duas respostas anteriores acertaram – eu não uso o UITabBarController no Tweetie. É muito fácil escrever um XXTabBarController personalizado (subclass simples do UIViewController ) que fica feliz em ser colocado em uma pilha de controladores de nav, mas ainda vive pela filosofia “view controller”. Cada “guia” na visualização específica da conta ( Tweets / Replies / Messages ) é seu próprio controlador de visualização e, no que diz respeito a eles, eles estão sendo trocados na canvas por um simples UITabBarController .

Eu estou construindo um aplicativo que usa uma estrutura de navegação semelhante ao Tweetie. Eu escrevi um post sobre como fazer isso no meu blog http://www.wiredbob.com, que também liga ao código-fonte. É um modelo completo que você pode usar e usar como base para outro projeto. Boa sorte!

É possível adicionar um UITabBar a qualquer UIViewController. Dessa forma, você não precisa realmente empurrar um UITabBarController e, portanto, permanecer dentro das diretrizes da API da Apple.

No construtor de interfaces, o UITabBar está em “Windows, Views & Bars” na biblioteca Cocoa Touch.

Eu faço isso em alguns dos meus aplicativos. O truque para adicionar uma barra de abas a um aplicativo baseado no navigationController é NÃO usar um TabBarController. Adicione uma barra de tabulação à exibição, torne o controlador de exibição para essa exibição um TabBarDelegate e responda às seleções do usuário na barra de guias no código do controlador de exibição.

Eu uso Tab Bars para adicionar visualizações adicionais à visualização da Barra de Guias como subvisualizações, para recarregar uma visualização de tabela com diferentes conjuntos de dados, para recarregar um UIPickerView, etc.

Eu estava lutando pela última hora para implementar uma UITabBar porque ela ficava oculta quando eu tentava exibir a minha visão; então eu encontrei este post :

Basicamente, certifique-se de inserir sua nova visualização abaixo da barra de guias, de acordo com essa linha de código:

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

No meu aplicativo, o controlador de visualização raiz é um controlador de UINavigation. Em um determinado momento no aplicativo, preciso exibir um UITabBar. Eu tentei implementar um UITabBar em um UIView dentro da hierarquia de navegação, como alguns dos posts anteriores sugeriram, e isso funciona. Mas descobri que queria mais do comportamento padrão que o controlador de guias fornece e encontrei uma maneira de usar o UITabBarController com o controlador UINavigation:

1) Quando eu quero exibir a visão do UITabBarController, eu faço isso:

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

2) Quando eu quero voltar para onde eu estava na hierarquia de navegação, eu faço isso:

 appDelegate.window.rootViewController = myNavControllerInstance; 

Foi assim que eu fiz. Isso está realmente empurrando um controlador de barra de ferramentas para o controlador de navegação. Funciona bem. Eu não encontrei em nenhum lugar na documentação que a Apple não suporta dessa forma. Alguém pode me dar um link para este aviso?

Se isso é verdade, é possível que a Apple se recuse a publicar meu aplicativo no 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]; } 

Isto pode ser conseguido simplesmente incorporando o TabBarController no Controlador de Navegação. No storyboard:

  1. Arraste um ViewController
  2. Clique na cena do ViewController
  3. Clique no editor >> Incorporar em >> Controlador de Navegação.
  4. Arraste um botão no mesmo ViewController.
  5. Arraste um TabBarController
  6. Conecte o botão no ViewController ao TabBarController via Push Segue Action.

Nesse caso, apenas o RootViewController do TabBarController estaria na pilha do Controlador de Navegação. Todos os TabBarItems teriam a Barra de Navegação no topo e o usuário pode ir para a Tela Inicial a qualquer momento, independentemente do TabBarItem selecionado.

Isso pode ser feito em qualquer ViewController na pilha do Controlador de Navegação.

Se funcionar, por favor me sugira como aumentar a reputação para que eu possa postar as imagens e o código na próxima resposta. 🙂

Eu escrevi um post no blog sobre como eu abordei esse problema. Para mim, usar uma exibição restrita era uma solução mais simples do que escrever uma implementação de barra de guias personalizada.

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