因为我对普通的 iPhone 标签栏有一些要求,它无法提供,所以我需要构建自己的标签栏。
如何构建自己的标签栏是最佳方式,具体来说,如何以正确的方式在我的主视图控制器中添加/删除(显示/隐藏)视图,考虑到子视图的内存和最佳实践?
如何构建自己的标签栏是最佳方式,具体来说,如何以正确的方式在我的主视图控制器中添加/删除(显示/隐藏)视图,考虑到子视图的内存和最佳实践?
UIKit
提供的核心导航类是一个好主意。你有什么类型的应用程序要求,认为需要完全自定义的选项卡栏类?通常可以通过子类化、分类或使用图层来实现必要的自定义。
更新1:以下是我在一些应用程序中实现自定义选项卡栏的方法:
UITabBar
的子类-updateTabBarImageForViewControllerIndex:
的自定义子类方法-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);
}
更新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;
}
这两个被接受的答案在iOS5中出现问题。相反,我所做的是保留自定义选项卡栏子类,并仅保留此方法:
- (void)drawRect:(CGRect)rect
{
CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, nil);
}
接着在MainWindow.xib中,我创建了一个自定义视图,其中UIImageView作为背景,而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;
}
这取决于您的应用程序。如果您有足够的内存来保留分配给选项卡栏的所有视图控制器,那么可以使用一个简单的数组来存储所有适当的视图控制器,并使用该数组中的索引显示它们。 创建自定义视图控制器也是一个好主意,它将存储自己的选项卡栏图像(和/或标题)。您的选项卡栏将从那里获取所有这些值。
如果您无法承受如此多的内存(但这不太可能),则可以在数组中存储NSDictionary而不是视图控制器。当用户点击选项卡栏项目时,您只需卸载先前的视图控制器并创建新的视图控制器,其中包含该字典中的参数。或者,您可以使用一些自定义容器类来代替字典。
UIKit
的 95% 工作,通过制作自己的选项卡栏(控制器)。为什么不通过一些简单的子类化或层内容操作来完成剩下的5%工作呢? - CIFilter
-drawRect:
方法中,您可以使用任何 Core Graphics 绘图例程来绘制线条、形状、渐变、文本和图像。最简单的方法是为每个选项卡栏项目使用图像,以完全覆盖标准选项卡栏。请参考我创建的 Tim McGraw 应用程序的截图:http://itunes.apple.com/us/app/tim-mcgraw/id341650507?mt=8 这是否与您对选项卡栏的需求一致? - CIFilter