Aide UINavigationController + TabBar

F007F007 Membre
00:28 modifié dans Vos applications #1
Bonjour,
je vous écris parce que je suis entrain de réaliser un projet informatique de calendrier iPhone (je suis étudiant en DUT info).
Seulement voila ces dernières semaines je bloque sur un point de l'application...
Je précise que je n'utilise pas Interface Builder mais que je "code tout à  la main".

J'utilise 4 vues dans mon application que j'affiche grace à  une Tabbar.
J'ai déclaré ma tabbar et mes vues dans mon appDelegate.


Dans une de mes vues j'ai un label et des boutons qui affichent le jour que l'on parcours.
En dessous de ça j'ai une UITableView qui affiche les événements du jour sélectionné.
Encore en dessous ma tabBar.
Tout en haut de la vue je voudrais une navigation bar avec des boutons pour créer des événements. Par exemple je voudrais un bouton + à  mettre à  droite (rightBarButtonItem).
Seulement voilà  je n'arrive pas à  l'afficher.

Ma vue est une subclass de UINavigationController.
Quand j'écris le code suivant rien ne s'affiche :

// ajout du bouton ajouter un nouvel événement<br />	UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addEvent:)];<br />	self.navigationItem.rightBarButtonItem = plusButton;<br />	[plusButton release];


Je vous joint un screen shot de l'appli pour que vous visualisiez mieux :
screencapturelf.png


Je vous remercie d'avance pour votre aide.

Réponses

  • muqaddarmuqaddar Administrateur
    00:28 modifié #2
    D'après ce que je lis, il faut que ta vue de AppDelegate charge ton UINavigationController, et que le RootViewController de ton UINavigationController soit un UITabBarController.

    Comme ça, tu peux avoir le mécanisme de UINavigationController pour chaque ViewController de ton TabBarController. Ainsi ton UITabBarController ne s'affichera que sur la vue 1 de ton UINavigationController.

    Lisant tes propos, je ne pense pas que ce soit l'inverse qu'il te faille.
  • dotshedotshe Membre
    février 2011 modifié #3
    Tout de suite je verrais deux solutions à  ton problème :

    Je suppose que chaque TabBarItem, charge un ViewController différent.

    1ère solution

    Tu n'as pas besoin d'avoir le mécanisme de navigation dans ton viewController, dans ce cas, tu ajoutes une navigationBar dans ta vue et ensuite tu pourras à  ta guise mettre des BarButtonItem (exemple ton bouton "+").


    Dans ton .m
    <br />- (void)viewDidLoad{<br />&nbsp; &nbsp; &nbsp; [super viewDidLoad];<br />&nbsp; &nbsp;  UINavigationBar *maNavBar = [[UINavigationBar alloc] init];<br />&nbsp; &nbsp;  /* configuration de la Navigation (frame, color, etc...)<br />&nbsp; &nbsp;  ....<br />&nbsp; &nbsp;  */<br /><br />&nbsp; &nbsp;  // Tu ajoute des items<br />&nbsp; &nbsp;  UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:@&quot;Mon Titre&quot;];<br />&nbsp; &nbsp;  navItem.rigthBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil]autorelease];<br />&nbsp; &nbsp; maNavBar.items = [NSArray arrayWithObject:navItem];<br /><br />&nbsp; &nbsp; [navItem release];<br /><br />&nbsp; &nbsp;  // Tu l&#39;ajoutes à  la vue de ton controller;<br />&nbsp; &nbsp;  [self.view addSubview:maNavBar];<br />&nbsp; &nbsp; [maNavBar release];<br />}<br /><br />
    


    2ème solution

    Tu veux pouvoir utiliser la navigation dans chacun de tes onglets. Dans ce cas dans le appDelegate :

    <br /><br />// Onglet 1<br />CalendarViewController *calendarController = [[CalendarViewController alloc] initWithNibName:nil bundle:nil];<br />UINavigationController *navCalendarController =[[UINavigationController alloc]initWithRootController:calendarController];<br />[calendarController release];<br /><br />// Pareil pour les autres onglets de la tabBar<br />...<br /><br />tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];<br />tabBarController.viewControllers = [NSArray arrayWithObjects:navCalendarController ,nil];<br /><br />[navCalendarController release];<br /><br />[window addSubview:tabBarController.view];<br />[windows makeKeyAndVisible];<br />
    


    Puis ensuite dans chaque viewController, tu auras un NavigationController.

    Et tu pourras ajouter tes boutons comme ceci :

    self.navigationItem.rigthBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil]autorelease];


    ps: il y a peut être des fautes de frappe dans le code car je l'ai fait depuis un poste Windows :( et je ne l'ai ainsi pas passé dans Xcode avant. Désolé.
  • F007F007 Membre
    00:28 modifié #4
    Très franchement, c'est parfait ! Merci beaucoup!
    Vous avez tout les deux été très réactifs et pédagogues (j'ai tout compris et corrigé mes erreurs en 2 minutes).
    (j'ai utilisé la deuxième solution).


    Je vais tout de même vous embêter encore un peu...

    Je cherche dans une vue semaine à  afficher les événements d'une semaine.
    Pour cela je récupère ces événements dans un NSMutableArray.

    J'ai utilisé un tuto (iPup) pour récupérer des événements d'une date à  une autre.
    Seulement ils utilisent des dates limites absolues (ceci m'oblige à  calculer l'écart entre aujourd'hui et la date limite).
    Pour éviter d'éventuels beugs je me demandais s'il était possible de définir cet intervalle entre deux dates toutes simple (dd/MM/YYYY à  dd/MM/YYYY).

    Je vous joint le code :
    (n_annee_debut n_annee_fin etc. représentent le calcul entre la date actuelle et la date recherchée).

    <br /><br />&nbsp; &nbsp; // initialisation de l&#39;event store <br />	eventStore = [[EKEventStore alloc] init];<br /><br />&nbsp; &nbsp; //on créé les dates limites pour le tri<br />&nbsp; &nbsp; CFGregorianDate gregorianStartDate, gregorianEndDate;<br /><br />&nbsp; &nbsp; CFGregorianUnits startUnits = {n_annee_debut,n_mois_debut,n_jour_debut,heureDebut,minutesDebut,0};<br />&nbsp; &nbsp; CFGregorianUnits endUnit = {n_annee_fin,n_mois_fin,n_jour_fin,heureFin,minutesFin,0};<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //récupere l&#39;heure actuelle dans la zonne où vous êtes placé<br />&nbsp; &nbsp; CFTimeZoneRef timezone = CFTimeZoneCopySystem();<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; gregorianStartDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timezone, startUnits), timezone);<br />&nbsp; &nbsp; gregorianEndDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timezone, endUnit), timezone);<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timezone)];<br />&nbsp; &nbsp; NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timezone)];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; CFRelease(timezone);<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; // On crée le prédicat<br />	NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];<br />	<br />	// On récupére tous les événements qui correspondent<br />	NSArray *events = [eventStore eventsMatchingPredicate:predicate];<br />
    



    Je vous remercie d'avance.
  • F007F007 Membre
    février 2011 modifié #5
    C'est bon j'ai réussi à  m'en sortir c'était tout con...

    <br />NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];<br />	//[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehaviorDefault];<br />	[dateFormatter setDateFormat:@&quot;YYYY-MM-dd HH:mm:ss&quot;];<br />&nbsp; &nbsp; <br />	NSDate *dateFromStringDebut;<br />&nbsp; &nbsp; NSString* dateStringDebut = [NSString stringWithFormat:@&quot;%d-%d-%d 00:00:00&quot;,n_annee_debut,n_mois_debut,n_jour_debut];<br />	dateFromStringDebut = [dateFormatter dateFromString:dateStringDebut];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; NSDate *dateFromStringFin;<br />&nbsp; &nbsp; NSString* dateStringFin = [NSString stringWithFormat:@&quot;%d-%d-%d 23:59:59&quot;,n_annee_fin,n_mois_fin,n_jour_fin];<br />	dateFromStringFin = [dateFormatter dateFromString:dateStringFin];<br /><br />
    



    Je bute tout de même sur un problème de NSMutableArray je vais certainement vous demander deux trois conseils dans la journée...


  • F007F007 Membre
    février 2011 modifié #6
    J'ai donc réglé mes problèmes.

    J'ai toute fois des questions portées maintenant sur la mémoire.

    J'utilise l'outils Leaks et Allocation dans Instruments.

    Après quelques modification sur mon code, l'outils Leaks ne détecte plus aucune fuite mémoire.
    Cependant je n'arrive pas à  comprendre comment faire pour que l'outils allocation fasse de même ;-)

    J'observe au total (après 5 minutes 35 d'utilisation)
    Live Bytes : 2.87 MB
    Si j'avais continué cela aurait été pire (logique non ?)
    Ce que je ne comprends pas c'est : pourquoi quand je change de vue ça augmente, puis ça diminue mais c'est un peu plus qu'au départ ?
    Forcement après quelque temps ça prend de la place en mémoire...

    Finalement j'ai même redécouvert une Leak :
    elle apparait quand je créé un événement lors de la saisie du titre et il me semble que c'est avec le correcteur orthographique.
    Mais le truc c'est que j'utilise le controleur de saisie d'événement intégré au SDK donc je vois pas comment je pourrais la corriger !
    Voici  ses caractéristiques :  Leaked Object : GeneralBlock16    Responsible Library : ProofReader  Responsible Frame : PRDbInit

    Bref si quelqu'un pouvait m'aider en m'expliquant si c'est normal ou pas mes chiffres...

    J'ai aussi quelque chose à  rajouter :

    j'utilise des objets que je partage dans toute mes classes : (classes singleton)
    J'ai par exemple un objet Mois avec lequel j'utilise des méthodes pour calculer des jours...

    je vous donne un exemple de code et j'aimerai savoir si je dois ajouter quelque chose à  propos de la mémoire pour l'améliorer ?
    - (void) calculMoisPrecedent:(id) sender {<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; if([[Mois sharedMois] numMois]==1) {<br />&nbsp; &nbsp; &nbsp; &nbsp; [[Mois sharedMois] setNumMois:12];<br />&nbsp; &nbsp; &nbsp; &nbsp; [[Mois sharedMois] setAnneeYY:([[Mois sharedMois] anneeYY]-1)];<br />&nbsp; &nbsp; &nbsp; &nbsp; [[Mois sharedMois] setAnneeYYYY:([[Mois sharedMois] anneeYYYY]-1)];<br />&nbsp; &nbsp; &nbsp; &nbsp; [nomAnneeLabel setText:[NSString stringWithFormat:@&quot;%d&quot;,[[Mois sharedMois] anneeYYYY]]];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; [[Mois sharedMois] setNumMois:[[Mois sharedMois] numMois]-1];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; [self rafraichirVue];<br />&nbsp; &nbsp; [nomMoisLabel setText:[[Mois sharedMois] nomMois]]; // on récupère le nom du mois<br />}<br /><br /><br />-(void) construireMois{<br />&nbsp; &nbsp; cadreVue = [[UIView alloc] initWithFrame:CGRectMake(2, 95, 324, 276)];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; int moisInt = [[Mois sharedMois] numMois];&nbsp; &nbsp;  <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; int premierJour=[[Mois sharedMois] jourFromDate:1]; //on récupere le premier jour du mois la fonction permet aussi de définir le nom, le nombre de jours du mois manipulé, le nombre de jours du mois précédent<br />&nbsp; &nbsp; int nbJoursMoisEnCours = [[Mois sharedMois] nbJourMoisEnCours]; //on recupere le nombre de jours du mois manipulé<br />&nbsp; &nbsp; int nbJoursMoisPrecedent = [[Mois sharedMois] nbJourMoisPrecedent]; //on récupère le nombres de jours du mois précédent de celui qu&#039;on manipule<br />&nbsp; &nbsp; BOOL bissextile = [[Mois sharedMois] anneeBissextile:[[Mois sharedMois] anneeYYYY]];<br /> <br />etc...<br /><br />
    


    Je vous remercie pour votre aide !
Connectez-vous ou Inscrivez-vous pour répondre.