仅使用一个视图控制器的具有多个选项卡的选项卡栏

Posted

技术标签:

【中文标题】仅使用一个视图控制器的具有多个选项卡的选项卡栏【英文标题】:Tab bar with multiple tabs using only one view controller 【发布时间】:2014-07-21 17:54:31 【问题描述】:

我在 SO 上找不到我的问题的答案,如果某个地方已经存在答案,请给我链接!我的问题似乎很常见-我在导航控制器中嵌入了一个表格视图,我想要一个带有 3 个项目的选项卡栏,其中 3 个项目更改表格视图以填充不同的数据,第一个选项卡表示视图时表格视图中的默认数据已加载。

但似乎没有必要为其他两个选项卡创建两个额外的 UITableViewController 类,因为我可以使用简单的[tableView reloadData] 简单地更改填充表格的数据。你是如何做到这一点的,以及如何在故事板中实现这一点?

【问题讨论】:

为什么要使用标签栏控制器来过滤表格视图的数据? 对不起,我不是说过滤器,我是说改变!我的应用程序显示来自 Facebook 页面的照片。专辑有 3 个类别,我希望 3 个选项卡代表类别,而 tableView 显示该类别中的专辑。 那么你需要三个视图控制器实例,但只有一个视图控制器类。只需将类别传递给类,以便视图控制器知道要显示哪些图像。 你能给我一些代码示例吗? 【参考方案1】:

在我看来,您真正想要的是一个带有 分段控件 来更改视图的单个 UITableViewController。标签栏用于导航

Segmented Control

使用 UIControlEventValueChanged 检测变化,加载新数据并重新加载视图。

您没有说明“不同的数据”是什么意思。如果您的意思是执行一些通过 CoreData 获取/谓词/排序等更新数据的操作,那么使用分段控件可能是要走的路。如果您的数据显着不同(不同的实体、不同的数据管理等),那么您可能应该使用单独的 UITableViewController,因为您不应该尝试过度概括您的 UITableViewController,而是将您的数据与您的 UITableViewController 配对。毕竟,这就是它的用途。

【讨论】:

死链接 - 截至 2018 年 6 月,尝试 Human Interface Guidelines > Controls > Segmented Controls - 或者,如果没有,请搜索字词 human interface guidelines segmented controls【参考方案2】:

您可以像这样使用 ctrl+drag 将多个关系 segue 到一个控制器。

storyboard> 5 times ctrl+drag to one Navigation Controller

你应该让 CustomTabBarController.swift 来修改标签。 不要忘记更改故事板中绘制的 TabBarController 的类名。

class CustomTabBarController: UITabBarController 
    let MENUS = ["tab1", "tab2", "tab3", "tab4", "tab5"]

    override func viewDidLoad() 
        super.viewDidLoad()

        let items = tabBar.items!

        for (var idx=0; idx<items.count; idx++) 
            items[idx].title = MENUS[idx]
            items[idx].tag = idx
        
    
...

您可以在 ViewController.swift 上使用标签或选定的标签索引

let tag = self.tabBarController?.tabBar.selectedItem!.tag

let selectedIndex = self.tabController?.selectedIndex

【讨论】:

【参考方案3】:

您可以做的是重用同一个类并检查viewDidLoad 方法以确定如何填充您的tableView,例如:

- (void)viewDidLoad
    //itemType is a property you set 
    //when instantiating the controller
    int index = self.itemType; 

    switch (index) 
        case 0:
            [self populateTab1];
            break;
        case 1:
            [self populateTab2];
            break;
        case 2:
            [self populateTab3];
            break;
        default:
            break;
    



【讨论】:

这并不理想。您正在强制视图控制器知道 1)它位于选项卡控制器中,2)其数据取决于所选选项卡。最好在视图控制器上简单地设置一些属性,告诉它要使用哪个数据集。这将使代码与特定布局的耦合度大大降低。 你说得对@rmaddy 这违反了关注点分离这只是我的第一个想法,我要编辑它【参考方案4】:

在情节提要中,将UITabbar 添加到您的表格视图控制器中。不要使用UITabbarViewController 作为视图控制器的容器。另一方面,UITabbar 只是一个控制单元。

将标签栏的委托设置为你的表格视图控制器,并添加以下协议方法:

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;

您可以在此方法中加载正确的数据。可以通过

获取选中项(按钮)的索引
NSUInteger index = [tabBar.items indexOfObject:item];

【讨论】:

以上是关于仅使用一个视图控制器的具有多个选项卡的选项卡栏的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有自定义选项卡 UI(不使用选项卡栏)的 UITabBarController 中删除“更多”选项卡

选项卡栏项显示具有模态序列的视图控制器

单击推送通知时,正确重定向到选项卡栏导航控制器内的视图控制器

iOS:选择选项卡之前的选项卡栏项目标题

以编程方式将选项卡栏控制器添加到当前 App Flow

将选项卡栏项与在其堆栈中显示第二个视图控制器的导航控制器相关联?