didSelectViewController在某些场合不会被调用

我有许多已经报告的问题, didSelectViewController不会被调用,但在我的情况下,它有时被调用。 我有三个选项卡和三个视图控制器。 每次用户按第二或第三个标签时,我需要执行一些代码。 在我的SecondViewController和ThirdViewController中,我有:

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

现在一切工作正常与SecondViewController, didSelectViewController被调用每次按下第二个选项卡。 同样在ThirdViewController didSelectViewController被调用,每次按下第三个选项卡,但只有当第二个栏同时没有按下。 所以当我在FirstViewController和ThirdViewController之间来回切换时,一切正常。 但是当我进入像first-> second-> third的模式,那么在ThirdViewController中没有调用SelectViewController。 另外,当我像第一,第三,第二,第三第三次didSelectViewController获取调用ThirdViewController第一次,但不是第二次。 有任何想法吗?

很难按照你正在做什么,但是从我所了解的你通过在SecondViewControllerThirdViewController之间来回更改UITabBarController的委托来响应标签开关。

如果这是真的,我会build议不要这样做。 相反,我会build议你尝试以下几点:

  • 分配一个永不改变的委托。 一开始,你可以使用你的应用程序委托,但如果你有一个专门的小class,这可能会更好。 我相信,现在你有一个不变的委托,它将得到所有调用tabBarController: didSelectViewController: 100%。
  • 作为委托的对象必须具有对SecondViewControllerThirdViewController实例的引用。 如果使用Interface Builder来deviseUI,可以通过将两个IBOutlet添加到委托类并将适当的实例连接到sockets来实现。
  • 现在,当委托收到tabBarController: didSelectViewController:它可以简单地将通知转发给SecondViewControllerThirdViewController ,具体取决于select哪个选项卡。

一个基本的代码示例:

 // 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]; } 

编辑

关于如何将上面的示例代码集成到您的项目中的一些提示:

  • TabBarControllerDelegate的实例添加到也包含TabBarController的.xib文件中
  • TabBarControllerdelegate出口连接到TabBarControllerDelegate实例
  • TabBarControllerDelegatesecondViewController出口连接到SecondViewController实例
  • TabBarControllerDelegatethirdViewController出口连接到ThirdViewController实例
  • SecondViewController添加一个方法- (void) doSomething
  • ThirdViewController添加一个方法- (void) doSomethingElse
  • 确保在SecondViewController没有任何代码,并且ThirdViewController更改TabBarController委托!

一旦你设置好了,一切正常,你可能会想清理一下:

  • 将通知方法doSomethingdoSomethingElse的名称更改为更明智的内容
  • 如果你按照评论中的讨论,也许你也想摆脱secondViewControllerthirdViewControllersockets

我也有这个问题,并厌倦了它。 我决定UITabBarController并覆盖下面的方法。 我这样做的原因是由于某种原因在应用程序启动setSelectedViewController:没有被调用。

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

我只是通过故事板上的这个教程挖掘,我想到了使用UITabBarControllerDelegate的替代scheme。 如果你想坚持UITabBarControllerDelegate然后随意忽略这个答案。

首先,创build一个UITabBarController的子类,让我们称之为MyTabBarController 。 在故事板编辑器中,您需要更改标签栏控制器的“Class”属性,以便故事板获取您的新课程。

将此代码添加到MyTabBarController.m

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

在故事板编辑器中,现在可以select连接到SecondViewControllerThirdViewController的两个segue,并ThirdViewController将segue标识符更改为“SecondVC”和“ThirdVC”。

如果我没有弄错,那就只需要这么做了。