【问题标题】:How do I use a UITabBarController using the same ViewController for every tab?如何使用 UITabBarController 为每个选项卡使用相同的 ViewController?
【发布时间】:2014-02-11 00:35:20
【问题描述】:

并根据选择的选项卡更改 ViewController 的内容和标题。

有可能吗?

以下是我在 UITabBarController 的 viewDidLoad 函数中尝试的内容

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    NSMutableArray * tabs = [[NSMutableArray alloc] init];

    EventsViewController * upcomingEvents = (EventsViewController *)[[self viewControllers] objectAtIndex:0];
    upcomingEvents.title = @"Upcoming Events";
    upcomingEvents.events = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"]];

    [tabs addObject:upcomingEvents];

    EventsViewController * myEvents = (EventsViewController *)[[self viewControllers] objectAtIndex:1];
    myEvents.title = @"My Events";
    myEvents.events = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MyEvents" ofType:@"plist"]];

    [tabs addObject:myEvents];

    [self.tabBarController setViewControllers:tabs animated:YES];

}

这会导致错误

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setEvents:]: unrecognized selector sent to instance 0x108fe3b50'

我当前的故事板设置

编辑:

最后从Unkn0wn.Bit得到一些帮助和理解。

我废弃了自定义的 UITabBarController,只是调整了我的 EventsViewController (UITableViewController) 中的 viewWillAppear 函数,以根据 tabBarController 的 selectedIndex 更改源。

使用两个单独的 NSMutableArrays(myEvents、comcomingEvents)有效地为多个 tabBar 按钮使用相同的视图(具有不同的信息)。

(void)viewWillAppear:(BOOL)animated {
    if([self.tabBarController selectedIndex]) {
        self.events = self.myEvents;
        self.navBar.title = @"My Events";
    } else {
        //temporary instead run function that either downloads events or tries to update if necessary
        self.events = self.upcomingEvents;
        self.navBar.title = @"Upcoming Events";
    }
}

【问题讨论】:

  • 是的,多次实例化。你尝试了什么?什么没用?显示代码。
  • 我发现这不是特别可靠,至少在iOS 8上是这样。 selectedIndex 的状态不会在正确的时间更新以进行一致的检测。
  • 我发现如果你把逻辑放在 viewDidLoad 中是非常可靠的......!

标签: ios objective-c


【解决方案1】:

这部分错误信息:

-[UINavigationController setEvents:]

告诉您您正在对UINavigationController 的实例调用setEvents:,但它没有响应。

您的问题是您忘记了视图控制器层次结构,因为您在导航控制器中有 EventsViewController 实例,因此您需要遍历层次结构以调用正确的实例。

即:

UINavigationController *navController = (UINavigationController *)[[self viewControllers] objectAtIndex:0];
EventsViewController *upcomingEvents = [navController topViewController];

【讨论】:

  • 您能否提供遍历层次结构以到达 EventsViewController 的示例?
【解决方案2】:

如果您使用界面生成器,请在您的故事板文件中创建多个视图控制器(从您的选项卡栏控制器按 ctrl+拖动以将它们分配给选项卡)根据需要设计您的视图,但将它们的自定义类设置为同一个类!

【讨论】:

  • 这实际上似乎与错误消息中描述的问题无关。
  • 我也认为这是一种解决方案,但我认为必须有一种方法可以在没有额外视图控制器的情况下做到这一点。
  • 我回答了问题标题中的问题。代码告诉了别的东西。我的解决方案是不使用viewDidLoad 中的代码,而是使用该机制使您的标签栏控制器工作!
  • 如果您不使用多个控制器,则组织视图会有些困难。这是一个安全和干净的选择!
  • 您可以查看当前选择了哪些标签栏项目!我猜代码类似于:[self.myTabBarController selectedIndex] 您可以在应用启动时实例化您的故事板,然后使用 segues 和标识符从根视图控制器监控您的去向。
【解决方案3】:

您可以使用ViewController 子类的多个实例,这样就可以满足您的需求。但是,如果您想简单地为每个实例使用完全相同的实例,那么您可能希望直接使用UITabBar,而不是UITabBarController。您可以将UITabBar 添加到您的UIViewController 子类并实现UITabBarDelegate 协议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    相关资源
    最近更新 更多