iPhone:我如何build立我自己的TabBar?
因为我有一个正常的iPhone TabBar不能提供的标签栏的一些要求,我需要build立自己的。
build立我自己的tabbar的最好方法是什么,特别是如何以正确的方式在我的主视图控制器中添加/删除(显示/隐藏)视图,同时考虑子视图的内存和最佳实践?
正如我在其他地方所说的,摆脱由UIKit
提供的核心导航类几乎不是一个好主意。 你认为什么types的应用程序需要一个完全自定义的标签栏类? 几乎总是可以通过子类化,分类或使用图层来实现必要的自定义。
更新1 :所以这就是我在我的一些应用程序中做了一个自定义标签栏实现。
- 创build
UITabBar
一个子类 - 向你的自定义子类中添加一个名为类似于
-updateTabBarImageForViewControllerIndex:
- 在Interface Builder中,将标签栏控制器的标签栏的类更改为您的自定义子类
- 在任何类符合您的标签栏控制器的委托(例如,您的应用程序委托),实现
-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; }