didSelectViewController在某些情况下不会被调用

时间:2013-07-08 19:20:39

标签: ios uitabbarcontroller

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

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

现在一切正常,使用SecondViewController,每次按下第二个选项卡时都会调用didSelectViewController。同样在ThirdViewController中didSelectViewController每次按下第三个选项卡时都会被调用,但仅在没有按下第二个选项卡的情况下被调用。所以当我在FirstViewController和ThirdViewController之间来回切换时,一切正常。但是当我进入第一个> second->第三个模式时,didSelectViewController不会在ThirdViewController中被调用。此外,当我第一次去>第三次>第二次>第三次didSelectViewController第一次在第三次调用时被调用,而不是第二次。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

我也有这个问题并且厌倦了它。我决定继承UITabBarController并覆盖以下方法。我之所以这样做的原因是因为某些原因导致应用程序启动setSelectedViewController:没有被调用。

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

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

答案 1 :(得分:5)

很难理解你到底在做什么,但据我所知,你通过在UITabBarControllerSecondViewController之间来回更改ThirdViewController的委托来回应制表符开关

如果这是真的,我建议不要这样做。相反,我建议你尝试以下方法:

  • 分配永不更改的委托。首先,您可以使用您的应用程序委托,但如果您有专门的小类可能会更好。我相信现在你有一个不变的代表,它将获得tabBarController: didSelectViewController:所有电话的100%。
  • 作为委托的对象必须同时引用SecondViewControllerThirdViewController个实例。如果您使用Interface Builder设计UI,则可以通过向委托类添加两个IBOutlet并将相应的实例连接到出口来实现此目的。
  • 现在,当代表收到tabBarController: didSelectViewController:时,它可以简单地将通知转发到SecondViewControllerThirdViewController,具体取决于所选的标签。

基本代码示例:

// 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文件中
  • delegate'的TabBarController出口连接到TabBarControllerDelegate实例
  • secondViewController的{​​{1}}出口连接到TabBarControllerDelegate实例
  • SecondViewController的{​​{1}}出口连接到thirdViewController实例
  • TabBarControllerDelegate
  • 添加方法ThirdViewController
  • - (void) doSomething
  • 添加方法SecondViewController
  • 确保- (void) doSomethingElseThirdViewController中没有任何代码更改SecondViewController代表!

一旦你完成所有工作并且一切正常,你可能想要清理一下:

  • 将通知方法ThirdViewControllerTabBarController的名称更改为更明智的内容
  • 如果您按照评论中的讨论进行,也许您还想摆脱doSomethingdoSomethingElse个网点

答案 2 :(得分:0)

我只是在故事板上挖掘this tutorial,我想到了使用UITabBarControllerDelegate的替代方案。如果你想坚持UITabBarControllerDelegate,那么请随意忽略这个答案。

首先,创建一个UITabBarController的子类,让我们称之为MyTabBarController。在故事板编辑器中,您需要更改选项卡栏控制器的“类”属性,以便故事板能够选择新的类。

将此代码添加到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];
  }
}

在情节提要编辑器中,您现在可以选择连接到SecondViewControllerThirdViewController的两个segue,并将segue标识符分别更改为“SecondVC”和“ThirdVC”。

如果我没有记错的话,那就是你需要做的一切。