2

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

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

现在,SecondViewController 一切正常,didSelectViewController每次按下第二个选项卡时都会调用。同样在 ThirdViewController 中didSelectViewController,每次按下第三个选项卡时都会调用,但仅在同时未按下第二个栏时调用。因此,当我在 FirstViewController 和 ThirdViewController 之间来回切换时,一切正常。但是当我进入像 first->second->third 这样的模式时,didSelectViewController不会在 ThirdViewController 中调用。此外,当我didSelectViewController第一次但不是第二次在 ThirdViewController 中调用 first->third->second->third 时。有任何想法吗?

4

3 回答 3

5

很难理解您到底在做什么,但据我了解,您通过在 和 之间来回更改 ' 代表来响应选项卡UITabBarController切换。SecondViewControllerThirdViewController

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

  • 分配一个永不改变的委托。首先,您可以使用您的应用程序委托,但如果您有一个专门的小班可能会更好。我敢肯定,现在您有一个不变的代表,它将获得 100% 的所有调用tabBarController: didSelectViewController:
  • 作为委托的对象必须同时引用SecondViewControllerThirdViewController实例。如果你正在使用 Interface Builder 设计你的 UI,你可以通过向IBOutlet委托类添加两个 s 并将适当的实例连接到插座来做到这一点。
  • 现在,当代理收到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到 .xib 文件中,该文件还包含TabBarController
  • delegate将 ' 的出口连接TabBarControllerTabBarControllerDelegate实例
  • secondViewController将出口连接TabBarControllerDelegateSecondViewController实例
  • thirdViewController将出口连接TabBarControllerDelegateThirdViewController实例
  • 添加一个方法- (void) doSomethingSecondViewController
  • 添加一个方法- (void) doSomethingElseThirdViewController
  • 确保您没有留下任何代码SecondViewControllerThirdViewController更改TabBarController委托!

一切就绪并且一切正常后,您可能需要进行一些清理:

  • 将通知方法的名称更改为doSomethingdoSomethingElse明智的名称
  • 如果您关注评论中的讨论,也许您也想摆脱secondViewControllerthirdViewController插座
于 2013-07-08T19:54:10.917 回答
5

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

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

- (void)setSelectedViewController:(UIViewController *)selectedViewController
{
    [super setSelectedViewController:selectedViewController];
    // my code
}
于 2013-07-08T19:48:27.157 回答
0

我刚刚浏览了这个关于故事板的教程,我想到了使用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];
  }
}

在故事板编辑器中,您现在可以选择连接到SecondViewController和的两个 segue,并将ThirdViewControllersegue 标识符分别更改为“SecondVC”和“ThirdVC”。

如果我没记错的话,这就是你需要做的。

于 2013-07-09T22:55:33.587 回答