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

时间:2011-02-06 06:28:04

标签: iphone ios uiview uitabbarcontroller uitabbar

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

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

3 个答案:

答案 0 :(得分:7)

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

更新1 :以下是我在某些应用中为自定义标签栏实现所做的工作。

  1. 创建UITabBar
  2. 的子类
  3. 向您的自定义子类添加一个名为-updateTabBarImageForViewControllerIndex:
  4. 的方法
  5. 在Interface Builder中,将标签栏控制器标签栏的类更改为自定义子类
  6. 无论哪个班级符合您的标签栏控制器的代理人(例如,您的应用代表),请在您的自定义标签栏子类上实施-tabBarController:shouldSelectViewController:并致电-updateTabBarImageForViewControllerIndex:
  7. 基本上,每次标签栏控制器要切换视图控制器时,您都希望通知标签栏子类。发生这种情况时,请确定需要为标签栏选择的图像。您的标签栏应该有n个图像,每个标签的选定状态一个。{1}}。实际上可以捏造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;
    }
    

答案 1 :(得分:0)

这实际上取决于您的申请。如果你能够保留内存中分配给tabbar的所有视图控制器,那么你可以使用一个简单的数组,它将存储所有适当的视图控制器,并使用该数组中的索引显示它们。 创建自定义视图控制器也是一个好主意,它将存储自己的标签栏图像(和/或标题)。而且你的tabbar会从那里获取所有值。

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

答案 2 :(得分:0)

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

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

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

在TabController委托中,我更新按钮的选定状态。

- (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;
}