【问题标题】:Suppress moreNavigationController in custom UITabBarController抑制自定义UITabBarController中的moreNavigationController
【发布时间】:2012-05-01 18:37:18
【问题描述】:

我已经为一个项目实现了一个自定义的 UITabBar 解决方案。本质上,如果有超过 5 个项目,我会使用一个 scrollView,它允许用户滚动其他选项卡项目并抑制更多按钮。在 Weather Channel 应用程序中可以看到类似的外观。

每个选项卡栏项对应一个 UINavigationController,它管理每个选项卡的视图堆栈。我遇到的问题是当我有超过 5 个选项卡项时,从选项卡 5 开始无法正确维护导航堆栈。似乎 moreNavigationController 会在您每次返回该选项卡时终止导航堆栈,并再次将您带到初始页面。

我已经重写了 setSelectedViewController 方法,如下所示:

- (void) setSelectedViewController:(UIViewController *)selectedViewController {
    [super setSelectedViewController:selectedViewController];
    if ([self.moreNavigationController.viewControllers count] > 1) {
        self.moreNavigationController.viewControllers = [[NSArray alloc] initWithObjects:self.moreNavigationController.visibleViewController, nil];
    }
}

此代码将删除左侧导航按钮上的更多功能,但不能解决维护导航堆栈的问题。所有其他选项卡工作正常。我可以遍历几个视图,并且在我离开并返回该选项卡后维护堆栈。我知道这是一个复杂的问题,所以请让我知道是否有我可以提供说明的地方。谢谢!

【问题讨论】:

    标签: ios


    【解决方案1】:

    这就是我最终解决这个问题的方式:

    - (void) setSelectedViewController:(UIViewController *) selectedViewController {
        self.viewControllers = [NSArray arrayWithObject:selectedViewController];
        [super setSelectedViewController:selectedViewController];
    }
    

    当您最初在 UITabBarController 上设置 viewControllers 时,基本上从 5 开始的任何选项卡都会将其导航控制器替换为 moreNavigationController。因此,我动态地将 viewControllers 设置为仅包含我正在单击的选项卡。在这种情况下,永远不会超过 1,因此 moreNavigationController 不会发挥作用。

    当我初始化我的自定义控制器时,我只提供第一个选项卡作为 viewControllers 以便应用程序可以加载。

    - (id) init {
        self = [super init];
        if (self) {
            self.delegate = self;
            [self populateTabs];
        }
        return self;
    }
    
    - (void) populateTabs {
        NSArray *viewControllers = [self.manager createViewsForApplication];
        self.viewControllers = [NSArray arrayWithObject:[viewControllers objectAtIndex:0]];
        self.tabBar.hidden = YES;
        MyScrollingTabBar *tabBar = [[MyScrollingTabBar alloc] initWithViews:viewControllers];
        tabBar.delegate = self;
        [self.view addSubview:tabBar];
    }
    

    为清楚起见,tabBar 委托设置为此类,以便它可以响应选项卡单击。委托方法如下:

    - (void) tabBar:(id) bar clickedTab:(MyScrollingTabBarItem *) tab {
        if (self.selectedViewController == tab.associatedViewController) {
            [(UINavigationController *) tab.associatedViewController popToRootViewControllerAnimated:YES];
        } else {
            self.selectedViewController = tab.associatedViewController; 
        }
        // keep nav label consistent for tab
        self.navigationController.title = tab.label.text;
    }
    

    【讨论】:

    • 我的做法完全不同,但使用了您的概念,即仅放置第一个 ViewController 并动态加载所有其他 ViewController。做得很好!
    【解决方案2】:

    您也可以覆盖 UITabBarController 的 moreNavigationController 变量并返回您自己的自定义 NavigaitonContorller,如下所示:

    override var moreNavigationController: UINavigationController { return MyCustomNavController() }

    在我需要一个允许在滚动时隐藏 NavigationBar 的 NavigaitonController 的情况下工作。

    至于隐藏 MoreNavigationController 的后退按钮,你可以将每个 NavigationItem 的 leftBarButtonItem 设置为任何值(甚至是空的 UIBarButtonItem),并且更多 NavigaitonController 的后退按钮会消失。

    【讨论】:

      猜你喜欢
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-26
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多