【问题标题】:Detect which Tab was selected on TabBarController from inside a TableViewController - Code Reuse从 TableViewController 内部检测在 TabBarController 上选择了哪个选项卡 - 代码重用
【发布时间】:2012-01-22 16:06:58
【问题描述】:

我有一个应用程序,它在 TabBarController 上有 5 个选项卡。为简单起见,假设它们是选项卡 A、B、C、D 和 E。每个选项卡将用户带到嵌入在导航控制器中的 TableViewController。每个选项卡也有自己特定的 .h 和 .m 文件。 5 个选项卡之间的大部分代码非常相似。我想取消这 5 组类文件,只使用 1 组。这将使我更容易对应用程序进行更改(在 1 个位置而不是 5 个位置)。如何在单个实现文件中检测选择了哪个选项卡?一旦我知道我可以放置逻辑来专门为选择哪个选项卡呈现 tableview...

我要提到的另一件事是我需要在 TableViewController 中检测选定的 Tab。 TabBarController 是应用程序的入口点,我没有 TabBarController 子类。

我在 TableViewController 中尝试了这段代码,但是它没有被访问和/或使用。

在 .h 文件中:

@interface MyController : UITableViewController <UITabBarDelegate>

在 .m 文件中:

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
    //NSLog(@"selectedIndex: %d", self.tabBarController.selectedIndex);

    NSLog(@"didSelectItem: %d", item.tag);
}

【问题讨论】:

  • 尝试将类似的代码放在一个类中,然后为 A、B、C、D 和 E VC 子类化五次。

标签: iphone ios5 uitabbarcontroller xcode4.2


【解决方案1】:

简单,你已经有了解决方案!

tabBarController

作为标签栏控制器的父级或祖先。 (只读)

@property(nonatomic, readonly, retain) UITabBarController *tabBarController

讨论如果receiver被添加到一个tab bar控制器,这个属性就是tab bar控制器。如果接收方的 导航控制器被添加到一个标签栏控制器,这个属性 是导航控制器的标签栏控制器。如果没有标签栏 present 或接收者是模态视图,此属性为 nil。

这意味着您添加到标签栏控制器的任何 viewController 都具有由系统填充的此属性。

然后在你想要的视图控制器中为你实现 viewWillAppear 的选项卡

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    NSUInteger selectedIndex = self.tabBarController.selectedIndex;
    switch (selectedIndex) {
        case 0:
            //configure me
            break;
        case 1:
            //configure me differently!!
            break;

        default:
            break;
    }
}    

根据 cmets,tabBarController 的这个属性似乎并不可靠。

您描述的问题听起来可以通过子类化来解决。为每个选项卡通用的代码创建一个 UIViewController 的子类,然后为每个选项卡 viewController 子类化您的子类,以对选项卡进行唯一的修改。

或者,您可以使用相同的类但不同的 xib 加载每个选项卡。您可以在界面构建器的“用户定义的运行时属性”部分中设置视图控制器的属性。然后在 viewWillAppear 块中检查 xib 在该实例上设置的属性。

【讨论】:

  • 好的!我想我们快到了,但是有一个问题。我在 ViewWillAppear 中有这段代码:NSUInteger selectedIndex = self.tabBarController.selectedIndex; NSLog(@"Selected Index: %d", selectedIndex); 当我运行应用程序时,索引不一致。示例:应用程序加载并且选项卡 A 在调试器中显示 Selected Index: 0,单击选项卡 B 显示 Selected Index: 1,选项卡 C 显示 Selected Index: 2,然后单击选项卡 A 应该显示 0 但显示 Selected Index: 2,选项卡 B 然后显示 Selected Index: 0等等……这很奇怪!有什么建议吗?
  • 更新 - 我忘了添加属性!现在我在 .h 文件 @property(nonatomic, readonly, retain) UITabBarController *tabBarController; 中有这段代码,在 .m 文件中有我之前注释中的代码。结果现在是每个选项卡的 Selected Index: 0 的输出 - 换句话说,它们都产生 0... 有什么建议吗?
  • 嗯。这似乎是一种竞争条件,其中视图被告知它将在选项卡栏控制器的选择更改之前出现。我已经验证这也发生在设备上。由于它第一次正常工作(并且假设您只需要第一次配置类),您可以存储一个 BOOL 以查看您之前是否已完成设置。
  • 您不需要添加属性。继承自 UIViewController
  • Jack - 你的最后一条评论提示我做以下两件事:1) 从 .h 文件中删除 @property。 2) 将 viewWillAppear 的代码 out 移出 in viewDidAppear 现在可以完美运行了!再次感谢您的帮助!!
【解决方案2】:

如果我理解正确,你有很多选择:
- 您可能想要覆盖 m 文件中的 init 方法,我猜它会初始化 UITableViewCOntroller 并根据您所在的选项卡向它传递一个附加参数。

  • 您可能还想为这个类添加一个tabid 属性,并在为每个选项卡创建它时设置它(显示您所在的选项卡)。

  • 你也可以使用通知(但这不是最简单或最好的解决方案,除非你有充分的理由不使用前两个)

  • 我相信还有很多其他方法。

【讨论】:

  • 阿里,是的,我正在考虑创建一个属性来跟踪 tabId 或 tabName(无论如何),但是我不确定如何“捕获”该选项卡名称......你能提供我有一个代码示例?提前致谢!
猜你喜欢
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
相关资源
最近更新 更多