didSelectViewController n'est pas appelé à certaines occasions

J'ai le problème que beaucoup ont déjà signalé, didSelectViewController n'est pas appelé, mais dans mon cas, il est parfois appelé. J'ai trois tabs et trois controllers de vue. Chaque fois que l'user appuie sur le deuxième ou le troisième onglet, je dois exécuter du code. Dans mon SecondViewController et ThirdViewController j'ai:

 UITabBarController *tabBarController = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController; [tabBarController setDelegate:self]; 

Maintenant, tout fonctionne bien avec le SecondViewController, le didSelectViewController est appelé chaque fois que le second onglet est pressé. De plus, dans ThirdViewController, didSelectViewController est appelé chaque fois que le troisième onglet est enfoncé, mais seulement lorsque la seconde barre n'est pas enfoncée. Donc, quand je commute entre FirstViewController et ThirdViewController, tout est OK. Mais quand je vais dans un model comme first-> second-> third, alors le didSelectViewController n'est pas appelé dans ThirdViewController. Aussi quand je vais comme premier-> troisième-> deuxième-> troisième didSelectViewController est appelé dans ThirdViewController la première fois mais pas la deuxième fois. Des idées?

Il est difficile de suivre exactement ce que vous faites, mais d'après ce que je comprends vous UITabBarController aux commutateurs d'tabs en modifiant le délégué de SecondViewController entre SecondViewController et ThirdViewController .

Si c'est vrai, je déconseille de le faire. Au lieu de cela, je vous suggère d'essayer ce qui suit:

  • Affectez un délégué qui ne change jamais. Pour commencer, vous pouvez utiliser le délégué de votre application, mais il serait probablement préférable d'avoir une petite class dédiée pour cela. Je suis sûr que maintenant vous avez un délégué non-changeant, il obtiendra 100% de tous les appels à tabBarController: didSelectViewController:
  • L'object qui est le délégué doit avoir une reference à la fois les instances SecondViewController et ThirdViewController . Si vous concevez votre interface user avec Interface Builder, vous pouvez le faire en ajoutant deux IBOutlet à la class déléguée et en connectant les instances appropriées aux points de vente.
  • Maintenant, lorsque le délégué reçoit tabBarController: didSelectViewController: il peut simplement transmettre la notification à SecondViewController ou ThirdViewController , en fonction de l'onglet sélectionné.

Un exemple de code de base:

 // TabBarControllerDelegate.h file @interface TabBarControllerDelegate : NSObject <UITabBarControllerDelegate> { } @property(nonatomic, retain) IBOutlet SecondViewController* secondViewController; @property(nonatomic, retain) IBOutlet ThirdViewController* thirdViewController; // TabBarControllerDelegate.m file - (void) tabBarController:(UITabBarController*)tabBarController didSelectViewController:(UIViewController*)viewController { if (viewController == self.secondViewController) [self.secondViewController doSomething]; else if (viewController == self.thirdViewController) [self.thirdViewController doSomethingElse]; } 

MODIFIER

Quelques conseils sur la façon d'intégrer l'exemple de code ci-dessus dans votre projet:

  • Ajouter une instance de TabBarControllerDelegate au file .xib qui contient également le TabBarController
  • Connectez la sortie delegate de TabBarController 'à l'instance TabBarControllerDelegate
  • Connectez la sortie secondViewController de TabBarControllerDelegate à l'instance SecondViewController
  • Connectez la sortie thirdViewController de TabBarControllerDelegate à l'instance ThirdViewController
  • Ajouter une méthode - (void) doSomething à SecondViewController
  • Ajouter une méthode - (void) doSomethingElse à ThirdViewController
  • Assurez-vous qu'il ne rest plus de code dans SecondViewController et que ThirdViewController modifie le délégué TabBarController !

Une fois que vous êtes tous set et que tout fonctionne correctement, vous voudrez probablement nettoyer un peu:

  • Changez les noms des methods de notification doSomething et doSomethingElse en quelque chose de plus sensé
  • Si vous avez suivi la discussion dans les commentaires, vous voudrez peut-être également vous débarrasser des sockets de thirdViewController secondViewController et thirdViewController

Moi aussi j'avais ce problème et j'en avais marre. J'ai décidé de sous- UITabBarController et de replace les methods suivantes. La raison pour laquelle j'ai fait les deux était pour une raison quelconque au lancement de l'application setSelectedViewController: n'était pas appelé.

 - (void)setSelectedIndex:(NSUInteger)selectedIndex { [super setSelectedIndex:selectedIndex]; // my code } - (void)setSelectedViewController:(UIViewController *)selectedViewController { [super setSelectedViewController:selectedViewController]; // my code } 

Je viens de creuser ce tutoriel sur les storyboards, et j'ai pensé à une alternative à l'utilisation de UITabBarControllerDelegate . Si vous voulez vous en tenir à UITabBarControllerDelegate n'hésitez pas à ignorer cette réponse.

Tout d'abord, créez une sous-class de UITabBarController , appelons-la MyTabBarController . Dans l'éditeur de storyboard, vous devez modifier la propriété "Class" du controller de la barre d'tabs pour que le storyboard reprenne votre nouvelle class.

Ajoutez ce code à MyTabBarController.m

 - (void) prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender { if ([segue.identifier isEqualToSsortingng:@"SecondVC"]) { SecondViewController* secondViewController = (SecondViewController*)segue.destinationViewController; [secondViewController doSomething]; } else if ([segue.identifier isEqualToSsortingng:@"ThirdVC"]) { ThirdViewController* thirdViewController = (ThirdViewController*)segue.destinationViewController; [thirdViewController doSomethingElse]; } } 

Dans l'éditeur de storyboard, vous pouvez maintenant sélectionner les deux segments qui se connectent à SecondViewController et ThirdViewController et changer l'identificateur de segment en "SecondVC" et "ThirdVC", respectivement.

Si je ne me trompe pas, c'est tout ce que vous devez faire.