[Résolu] Soucis : Combinaison Tabbar / TableView et NavigationController.

ceburoceburo Membre
avril 2011 modifié dans API UIKit #1
Bonjour tout le monde.

Donc petit souci avec une combinaison d'éléments UITabbarController, de TableViewController et de NavigationController.

Je suis parti d'un template Tabbar. Mon 4eme onglet est censé contenir une TableView avec une navigationBar au dessus.

Le problème c'est que la TableView apparaà®t très bien, mais pas la NavigationBar  :o .

Quel peut-être le problème ?

Merci à  vous.
«1

Réponses

  • muqaddarmuqaddar Administrateur
    00:44 modifié #2
    Il y a des chances que ta navigationBar soit une cinquantaine de pixels plus haut... soit la hauteur de la tabBar.
    Il faudrait la repositionner. Tu peux déjà  essayer "bêtement" de la descendre dans IB pour voir si c'est bien ça.
  • ceburoceburo Membre
    00:44 modifié #3
    Merci pour la réponse rapide.

    Alors le truc c'est que apparemment, comme je suis sur un UITableViewController, je ne peux pas ajouter de NavigationBar en la glissant sur l'interface. J'ai juste indiqué dans la section "Simulated Metrics" de mon xib que la top bar est une NavigationBar.

    De la même manière que j'ai indiqué que la bottom bar est une Tabbar, mais elle, elle s'affiche sans soucis.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #4
    J'ai juste indiqué dans la section "Simulated Metrics" de mon xib que la top bar est une NavigationBar.


    Bein justement, cherche pas plus loin.
    Si ce sont des simulated metrics, c'est que ce sont des éléments fictifs.

    Mais tu l'as ajouté par le code alors ?
    Bon sinon fait un UIViewController, et ajoute une tableView avec outlet + ta navigationBar (la vraie) dans IB.

    De la même manière que j'ai indiqué que la bottom bar est une Tabbar, mais elle, elle s'affiche sans soucis.


    Là , oui c'est normal !
  • ceburoceburo Membre
    00:44 modifié #5
    La solution du UIViewController "de base" est celle que j'ai commencé hier soir, après mon message.

    Niveau affichage, ça fonctionne, il me reste plus qu'à  regarder comment, par exemple, changer le titre par le code. A ce que je vois self.navigationItem... ne marche pas  :( . Pourtant cela marchait sur un template de TableView.

    J'ai bien ajouter <UINavigationBarDelegate, UINavigationControllerDelgate>.

    Je regarderait dans la doc ce soir, je ne pourrais pas toucher au code avant.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #6
    [self.navigationBar.topItem setTitle:@&quot;tittle&quot;];
    
  • ceburoceburo Membre
    00:44 modifié #7
    Et que penses-tu du fait que self.navigationItem.(quelque chose) ne marche pas ?

    P.S : j'essairai le self.navigationBar à  midi si j'ai le temps.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #8
    Dans mon cas, il faut qu'il y ait bien sûr un outlet vers la navigationBar hein...

    self.navigationItem doit marcher si tu fais un outlet vers le navigationItem et pas la NavigationBar peut-être...
  • ceburoceburo Membre
    00:44 modifié #9
    o:) OK pour la navigationBar. Elle fonctionne.

    Par contre, la TableView ne veut rien savoir.

    Voici le .h.
    #import &lt;UIKit/UIKit.h&gt;<br /><br /><br />@interface ForthViewController : UIViewController &lt;UINavigationBarDelegate, UINavigationControllerDelegate, UITableViewDelegate, UITableViewDataSource&gt;{<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; IBOutlet UINavigationBar *navBar;<br />&nbsp; &nbsp; IBOutlet UITableView *tableVue;<br />}<br />@end<br />
    


    et le .m correspondant.
    #import &quot;ForthViewController.h&quot;<br /><br /><br />@implementation ForthViewController<br /><br />- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil<br />{<br />&nbsp; &nbsp; self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // Custom initialization<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br />- (void)dealloc<br />{<br />&nbsp; &nbsp; [navBar release];<br />&nbsp; &nbsp; [tableVue release];<br />&nbsp; &nbsp; [super dealloc];<br />}<br /><br />- (void)didReceiveMemoryWarning<br />{<br />&nbsp; &nbsp; // Releases the view if it doesn&#039;t have a superview.<br />&nbsp; &nbsp; [super didReceiveMemoryWarning];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; // Release any cached data, images, etc that aren&#039;t in use.<br />}<br /><br />#pragma mark - View lifecycle<br /><br />- (void)viewDidLoad<br />{<br />&nbsp; &nbsp; [super viewDidLoad];<br />&nbsp; &nbsp; // Do any additional setup after loading the view from its nib.<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; navBar.topItem.rightBarButtonItem = self.editButtonItem;<br />&nbsp; &nbsp; navBar.topItem.title = @&quot;Mon garage&quot;;<br />}<br /><br />- (void)viewDidUnload<br />{<br />&nbsp; &nbsp; [navBar release];<br />&nbsp; &nbsp; navBar = nil;<br />&nbsp; &nbsp; [tableVue release];<br />&nbsp; &nbsp; tableVue = nil;<br />&nbsp; &nbsp; [super viewDidUnload];<br />&nbsp; &nbsp; // Release any retained subviews of the main view.<br />&nbsp; &nbsp; // e.g. self.myOutlet = nil;<br />}<br /><br />- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation<br />{<br />&nbsp; &nbsp; // Return YES for supported orientations<br />&nbsp; &nbsp; return (interfaceOrientation == UIInterfaceOrientationPortrait);<br />}<br /><br />#pragma mark - Table view data source<br /><br />- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView<br />{<br />#warning Potentially incomplete method implementation.<br />&nbsp; &nbsp; &nbsp; &nbsp; // Return the number of sections.<br />&nbsp; &nbsp; return 0;<br />}<br /><br />- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section<br />{<br />#warning Incomplete method implementation.<br />&nbsp; &nbsp; &nbsp; &nbsp; // Return the number of rows in the section.<br />&nbsp; &nbsp; return 0;<br />}<br /><br />- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath<br />{<br />&nbsp; &nbsp; static NSString *CellIdentifier = @&quot;Cell&quot;;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />&nbsp; &nbsp; if (cell == nil) {<br />&nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; // Configure the cell...<br />&nbsp; &nbsp; cell.textLabel.text = @&quot;Cellule de test&quot;;<br /><br />&nbsp; &nbsp; return cell;<br />}<br /><br />@end<br />
    


    Jamais l'appli ne passe dans "(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath" par exemple.

    Dans IB, j'ai lié le delegate et le datasource de ma tableView au File's owner.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #10
    dans 1302693572:

    Jamais l'appli ne passe dans "(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath" par exemple.


    Normal tu renvoie aucune section, ni aucune row dans les méthodes précédentes, il va pas aller voir ce qu'il faut afficher... ;)
    T'as relié l'outlet du tableView aussi hein ? ;)
  • ceburoceburo Membre
    00:44 modifié #11
    Pffffff, quel ane je fais. Plus de 6 mois sans toucher à  XCode est voilà  le résultat.

    Tu as raison sur les 2 points :
    • 0 sections, 0 lignes, déjà  ça part mal,
    • Outlet déclaré mais je crois, pas relié, mais a confirmé ce soir. Je l'ai fait avec le "command+glisser" de xcode 4 (il le relie tout seul non ?.
  • ceburoceburo Membre
    00:44 modifié #12
    Tout est rentré dans l'ordre au niveau des cellules.


    Par contre, ce bout de code :
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{<br />&nbsp; &nbsp; &nbsp; &nbsp; // Navigation logic may go here. Create and push another view controller.<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; detailVoitureController *detailViewController = [[detailVoitureController alloc] initWithNibName:@&quot;detailVoiture&quot; bundle:[NSBundle mainBundle]];<br />&nbsp; &nbsp; &nbsp; &nbsp; // ...<br />&nbsp; &nbsp; &nbsp; &nbsp; // Pass the selected object to the new view controller.<br />&nbsp; &nbsp; [self.navigationController pushViewController:detailViewController animated:YES];<br />&nbsp; &nbsp; [detailViewController release];<br />&nbsp; &nbsp; detailViewController = nil;<br />&nbsp; &nbsp; <br />}<br />
    



    ne fonctionne pas.
    Je passe bien dedans, mais ni plantage, ni changement à  l'écran.


    C'est toujours sur la même classe que précédemment.


    Help, c'est un des derniers gros points qui me bloque.[/code]
  • muqaddarmuqaddar Administrateur
    00:44 modifié #13
    2 choses:

    - ARghhh, une classe sans majuscule, j'ai failli avaler de travers !
    detailVoitureController => DetailVoitureController

    C'est une convention de nommage quasi-obligatoire.

    - pour ton problème, essaie ça:
    [self pushViewController:detailViewController animated:YES];
    
  • ceburoceburo Membre
    00:44 modifié #14
    Ha ben oui mais faut pas manger en même temps que regarder le forum aussi. Tu prends des risques inconsidérés.

    Pour revenir au soucis, ce n'est pas ça. Comme ça l'appli plante en me disant "Unrecognize selector". C'est pour ça qu'il faut passer par self.navigationController.

    Je précise que j'ai bien <UINavigationControllerDelegate, ...> dans mon .h.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #15
    Mais tu es bien dans un contexte de NavigationController ?
    (parce plus haut tu parlais de tabbar...)
  • ceburoceburo Membre
    00:44 modifié #16
    Ben non justement, c'est ça l'astuce.

    Je suis à  la base, dans une tabbar. Cet onglet de ma tabbar contient une tableView avec une navigationBar en haut, et je voudrais passer à  une autre vue en sélectionnant un élément de la tableView.

    La tableView est bien remplie, j'ai une navigationBar, mais rien ne se passe quand je sélectionne un élément. Mais le code passe bien dans la procédure que j'ai collé juste avant.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #17
    Tu te rends compte que tu appelles un fonctionnement de NavigationController alors qu'aucun navigationController n'a été instancié !
    C'est normal que ça marche pas.

    Il ne faut pas ajouter une pov' navigation bar... mais un bien tout un mécanisme de NavigationController dans la vue de ta UITabBar... et c'est beaucoup plus compliqué.

    D'autre part, je ne sais pas si c'est vraiment recommandé de mettre un UINavigationController dans un seul de tes TabBar... c'est pas très ergonomique tout ça.

    IL faudrait faire l'inverse. Mettre un UINavigationController, et dans le rootViewController de celui-là  mettre ton UITabBarcontroller, Seul l'onglet concerné aurait un push vers le second écran du navigation Controller.
  • iSofTomiSofTom Membre
    00:44 modifié #18
    Oula, qu'est-ce que tu racontes muqaddar ?

    Mettre un UITabBarController dans un UINavigationController ? ???

    Deux problèmes:
    - point de vue technique: D'après la doc d'Apple, un UITabBarController DOIT être en root!
    - point de vue ergonomique: dès que tu push un nouveau viewController, tu ne vois plus ta tabBar!

    Sinon ceburo, il faut bien mettre ton controller contenant ta tableView dans un UINavigationController et lui même dans ta TabBarController.
  • ceburoceburo Membre
    00:44 modifié #19
    Alors si ça peut aider, voilà  une capture de la TableView, elle se trouve dans une TabBar et je voudrais y ajouter le comportement de UINavigationController.

  • muqaddarmuqaddar Administrateur
    00:44 modifié #20
    dans 1302721496:

    Oula, qu'est-ce que tu racontes muqaddar ?

    Mettre un UITabBarController dans un UINavigationController ? ???

    Deux problèmes:
    - point de vue technique: D'après la doc d'Apple, un UITabBarController DOIT être en root!



    Bah, oui, donc il peut très bien être dans le rootViewController du UINavigationController.

    dans 1302721496:

    - point de vue ergonomique: dès que tu push un nouveau viewController, tu ne vois plus ta tabBar!


    Oui, mais c'est pas forcément utile, surtout si ce qui est dans le deuxième écran ne se rapporte qu'au contenu du tab bar en question.

    Maintenant, il a les 2 choix, ça dépend du contexte et de ce qu'il veut faire.
    Mais dans tous les cas, il faudra une vraie instance de UINavigationController, ce qu'il n'a pas fait.
  • iSofTomiSofTom Membre
    avril 2011 modifié #21
    Pardon, je n'ai effectivement pas été très clair. Je voulais dire la vue d'un UITabBarController doit être placée en root de le Window!

    Doc apple:
    When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller


    Sinon effectivement il lui faut une instance de UINavigationController
  • ceburoceburo Membre
    00:44 modifié #22
    Alors petite piste, le push semble bien fonctionner car voici en debug ce que j'ai. Regardez dans self.navController._viewControllers...


    Mais bien entendu, aucun changements à  l'écran.
  • ceburoceburo Membre
    00:44 modifié #23
    Et voilà  à  quoi ressemble ma création d'interface.


    Maintenant à  l'éxécution, la NavigationBar n'apparaà®t plus. Mais le push a toujours le même comportement.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #24
    dans 1302723504:

    Pardon, je n'ai effectivement pas été très clair. Je voulais dire la vue d'un UITabBarController doit être placée en root de le Window!

    Doc apple:
    When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller



    Moi, j'en ai et je vois vraiment pas en quoi c'est une hérésie. ;)

    J'ai un UITabbarController installé dans le rootViewController d'un UINavigationcontroller lui-même installé dans une modaleViewController... ;) Et tout se passe bien, et je ne vois pas de pb d'ergonomie.
  • ceburoceburo Membre
    00:44 modifié #25
    Si j'envois le .zip du projet, c'est possible que quelqu'un jette un coup d'oeil ? :(
  • ceburoceburo Membre
    00:44 modifié #27
    Je ne suis pas trop loin si on regarde ma dernière capture. Sauf que je n'ai pas mis le NavigationController au niveau du tabbar mais directement dans le xib.

    J'essairai cette solution à  midi.
  • ceburoceburo Membre
    00:44 modifié #28
    ;D Ca marche !!!!

    Merci les gars.

    Par contre, juste une dernière question avant de clore le topic : ma view detailVoiture (celle qui est appelé quand on sélectionne un élément de la tableView) quand elle s'affiche, ne recouvre pas la tabbar. Comment faire pour qu'elle la cache (si c'est possible)?
  • iSofTomiSofTom Membre
    00:44 modifié #29
    Le mieux c'est que tu fasses un presentModalViewController
    Et du coup pas besoin de NavigationController  :D
  • ceburoceburo Membre
    00:44 modifié #30
    Ha ben oui mais maintenant que ça marche ... je vais le garder mon NavigationController  :P .

    Tant pis, y'aura la tabbar, c'est juste moins esthétique.
  • muqaddarmuqaddar Administrateur
    00:44 modifié #31
    Ma deuxième solution était donc valable puisqu'elle chasse le UITabBarController... lorsque l'on pushe. ;)
Connectez-vous ou Inscrivez-vous pour répondre.