iPhone:我如何build立我自己的TabBar?

因为我有一个正常的iPhone TabBar不能提供的标签栏的一些要求,我需要build立自己的。

build立我自己的tabbar的最好方法是什么,特别是如何以正确的方式在我的主视图控制器中添加/删除(显示/隐藏)视图,同时考虑子视图的内存和最佳实践?

正如我在其他地方所说的,摆脱由UIKit提供的核心导航类几乎不是一个好主意。 你认为什么types的应用程序需要一个完全自定义的标签栏类? 几乎总是可以通过子类化,分类或使用图层来实现必要的自定义。

更新1 :所以这就是我在我的一些应用程序中做了一个自定义标签栏实现。

  1. 创buildUITabBar一个子类
  2. 向你的自定义子类中添加一个名为类似于-updateTabBarImageForViewControllerIndex:
  3. 在Interface Builder中,将标签栏控制器的标签栏的类更改为您的自定义子类
  4. 在任何类符合您的标签栏控制器的委托(例如,您的应用程序委托),实现-tabBarController:shouldSelectViewController:并调用-updateTabBarImageForViewControllerIndex:在您的自定义标签栏的子类

基本上,每次标签栏控制器要切换视图控制器时,都要通知您的标签栏子类。 发生这种情况时,请确定您需要为选项卡select哪个图像。 您的标签栏应该有n图像,每个标签的选定状态一个。 实际上,我们可能会对UITabBarItem的实现进行模糊处理,并且只对单个图像进行处理,但是这只是一点点工作。

 // MyAppDelegate.m - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { // Determine the index based on the selected view controller NSUInteger viewControllerIndex = ...; [(MyTabBar *)tabBarController.tabBar updateTabBarImageForViewControllerIndex:viewControllerIndex]; return YES; } // MyTabBar.m - (void)updateTabBarImageForViewControllerIndex:(NSUInteger)index { // Determine the image name based on the selected view controller index self.selectedTabBarImage = [UIImage imageNamed:...]; [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, self.selectedTabBarImage.CGImage); } 

更新2 :现在我想到了更多,你实际上可以(而且应该)脱离你想要实现的东西,而不需要UITabBar 。 导入<QuartzCore/QuartzCore.h>并利用图层内容。 🙂

 // MyAppDelegate.m - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { // Determine the image name based on the selected view controller CGImageRef newTabBarImageRef = [[UIImage imageNamed:...] CGImage]; tabBarController.tabBar.layer.contents = (id)newTabBarImageRef; return YES; } 

这真的取决于你的应用程序。 如果你可以负担得起的所有视图控制器,分配给你的标签栏,那么你可以使用一个简单的数组,将存储所有适当的视图控制器,并使用该数组中的索引显示它们。 创build自定义视图控制器也是一个好主意,它将存储它自己的tabbar图像(和/或标题)。 而你的tabbar会从那里取所有的值。

如果你不能承受这么多的内存(但这不是很可能),那么你可以将NSDictionary存储在数组中,而不是查看控制器。 当用户点击tabbar项目时,只需卸载前一个视图控制器,并使用该字典中的参数创build新的视图控制器。 或者,而不是字典,你可以使用一些自定义的容器类。

这两个接受的答案在iOS5中打破。 我所做的是保持自定义标签栏子类,并只保留此方法不变:

 - (void)drawRect:(CGRect)rect { CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, nil); } 

然后在MainWindow.xib中,我创build了一个自定义视图,其中一个imageview作为背景,UIButtons作为标签栏项目。

在TabController委托中,我更新了button的选定状态。

 - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { // Determine the index based on the selected view controller UIButton *newBtn; if(viewController == homeVC) { ... } // Update the buttons newBtn.selected = YES; _selectedTabBtn.selected = NO; _selectedTabBtn = newBtn; return YES; }