iPhone:我如何构建自己的TabBar?

Nic*_*ard 4 iphone uitabbarcontroller uiview uitabbar ios

因为我对普通iphone标签栏无法提供的标签栏有一些要求,所以我需要自己构建.

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

CIF*_*ter 7

正如我在其他地方所说的那样,摆脱由其提供的核心导航类几乎绝不是一个好主意UIKit.您认为哪种类型的应用程序要求值得完全自定义标签栏类?几乎总是可以通过子类化,分类或使用图层来实现必要的自定义.

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

  1. 创建一个子类 UITabBar
  2. 在自定义子类中添加一个方法,例如 -updateTabBarImageForViewControllerIndex:
  3. 在Interface Builder中,将选项卡栏控制器的选项卡栏的类更改为自定义子类
  4. 无论哪个类符合您的标签栏控制器的委托(例如,您的应用程序委托),在您的自定义标签栏子类上实现-tabBarController:shouldSelectViewController:并调用-updateTabBarImageForViewControllerIndex:

基本上,每次标签栏控制器要切换视图控制器时,您都希望通知标签栏子类.发生这种情况时,请确定需要为标签栏选择的图像.您应该有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);
}
Run Code Online (Sandbox Code Playgroud)

更新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;
}
Run Code Online (Sandbox Code Playgroud)