在iPhone应用开发中TabBarController是一个很常用的应用模板,通过Tab可以横向地划分不同功能模块供用户选择。如果使用恰当不仅可以改进产品的用户体验,而且可以初步完成实现时的模块划分。不过Apple出对界面一致性的考虑,严格限制了UITabBarController风格定制。但开发者出于实际需求的考虑又经常会有这方面的需求以实现应用的差异化。我们在目前项目的开发中就遇到了这样的一个问题。首先参照UITabBarController解构TabBarController,其相关类的关系如下:

自定义TabBarController_第1张图片    其中,TabButton是一个双态的Button(选中和未选中),行为和CheckBox和RadioButton类似。TabBar是TabButton的容器, 负责TabButton的排布和互斥,保证同时只有同时只有一个Button为选中态。TabBarController包含了TabBar,并管理这一个ViewController的栈,在TabBar上的按钮点击时对栈上的ViewController位置进行相应的调整,从而保持TabBar和ViewController栈之间的一致性。

 

经过一番调查后发现了两种实现方案。

1 替换部分现有的实现

目标是替换掉系统的部分控件,调查后发现可以通过隐藏TabBar实现。隐藏时可以访问UITabBarController的tabBar属性,代码如下:

- (void) hideBuildinTabBar {

    [[self tabBar] setHidden:YES];

}

    隐藏后就可以加入你自己定制的TabBar了,关键一步就是不要忘了在TabBar的当前选中按钮变化时通过UITabBarController的setSelectedIndex接口设定ViewController栈的当前ViewController。

具体实现参照《How To Customise the Tab Bar (UITabBar) in an iPhone Application》

 

2 从头开始实现

    相关类的设计可以参见上述的类结构图,具体参照github上的开源项目BCTabBarController。

 

小结:

    第一种方法相对比较简单,而且可以充分利用IB进行创建,但隐藏的TabBar在一些系统的切换动画中需要特殊处理,否者会在切换刹那间浮现,从而影响用户体验。第二种方法相对就比较彻底,但代价就是需要实现多个类,若要达到和系统提供的类相同的功能和稳定性,设计和代码实现上都要求较高。