【问题标题】:Programmatically setting UITabBarController's viewControllers and selectedIndex results in no selected UITabBarItem以编程方式设置 UITabBarController 的 viewControllers 和 selectedIndex 导致没有选择的 UITabBarItem
【发布时间】:2014-04-07 06:15:38
【问题描述】:

我在 iOS 6 和 7 中都有一个奇怪的错误,下面是 UITabBarController 子类代码:

self.viewControllers = @[self.myKitchenNavigationController,
                         self.photosIndexNavigationController,
                         self.postNavigationController,
                         self.feedNavigationController,
                         self.talkNavigationController];

self.selectedIndex = 0;
// self.selectedViewController = self.myKitchenNavigationController; // This doesn't help either

如果我以编程方式设置viewControllers(以前的nil)并立即设置selectedIndex,那么标签栏会出现而没有选择。

我的印象是,在修改控制器之后设置一个选定的索引有点“太”快了,所以我将该调用封装在一个 dispatch_async 调用中:

// Fix selection by dispatching async
dispatch_async(dispatch_get_main_queue(), ^
{
    self.selectedIndex = 0;
});

现在它可以工作了,但我想知道这是否是 SDK 长期存在的错误。


其实bug还在,完整方法:

- (void)setMode:(RootViewControllerMode)mode
{
    if (_mode == mode)
        return;

    NBULogInfo(@"%@ %d", THIS_METHOD, mode);

    _mode = mode;

    switch (mode)
    {
        case RootViewControllerLoggedMode:
        {
            self.viewControllers = @[self.myKitchenNavigationController,
                                     self.photosIndexNavigationController,
                                     self.postNavigationController,
                                     self.feedNavigationController,
                                     self.talkNavigationController];

            // Fix selection by dispatching async
            dispatch_async(dispatch_get_main_queue(), ^
            {
                self.selectedIndex = 0;
            });

            // Adjust post button
            self.postButtonHidden = NO;
            [self.view addSubview:self.postButton];
            break;
        }
        case RootViewControllerNotLoggedMode:
        {
            self.viewControllers = nil;

            // Remove post button to tabBar
            [self.postButton removeFromSuperview];
            break;
        }
        default:
        case RootViewControllerEmptyMode:
        {
            self.viewControllers = nil;
            break;
        }
    }
}

这是唯一触及标签栏控制器的viewControllers 和当前选定标签的代码。

已经验证了这是在主线程上调用的,然后还尝试将dispatch_async中的所有内容包装在主队列中,最后尝试dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(),但问题仍然存在。

【问题讨论】:

  • 你在 UITabBarController 子类中设置“self.viewControllers”在哪里?
  • - (void)setMode:(RootViewControllerMode)mode 属性中,该属性在成功登录时被关闭之前被模式登录控制器调用,因此在所有视图和控制器都已加载之后。
  • 我猜你在登录 api 的完成处理程序中设置 viewcontrollers,或者在可能未在 mainthread 中运行的委托函数中设置 selectedindex 不起作用,尽管您通过在调度主线程中更改 UI 得到了正确的解决方案。
  • 可能是的!尽管在我编辑问题之前它也与dispatch_get_current_queue() 一起使用。我试试看。
  • 好吧,刚刚检查过了,setMode: 正在从 mainThread 中调用。

标签: ios objective-c uitabbarcontroller uitabbaritem


【解决方案1】:

修改标签栏的viewControllers 似乎很容易引起错误提示,除了这里的问题之外,selectionIndicatorImage 后面有时还会出现标签项标记。

我们最终将控制器设置在情节提要中,并避免修改控制器或其顺序。

【讨论】:

    【解决方案2】:
    YourAppDelegate* appDelegate = (id)[UIApplication sharedApplication].delegate;
    appDelegate.yourTabBar.selectedIndex = 1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      • 2018-03-04
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多