我们这里不用Main.storyBoard作为程序的主窗口,我们采用代码来自己创建窗口。
下面来到AppDelegate.m,#import "TabBarController.h"(这是我们自定义的UITabBarController,继承自UITabBarController)
在程序启动方法里创建窗口,并设置窗口的根控制器为我们自定义的TabBarController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 创建窗口
self.window = [[UIWindow alloc] init];
self.window.frame = [UIScreen mainScreen].bounds;
// 设置窗口的根控制器
self.window.rootViewController = [[TabBarController alloc] init];;
// 显示窗口
[self.window makeKeyAndVisible];
return YES;
}
//
// TabBarController.m
#import "TabBarController.h"
#import "TabBar.h"
#import "EssenceViewController.h"
#import "NewViewController.h"
#import "FriendTrendsViewController.h"
#import "MeViewController.h"
@interface TabBarController ()
@end
@implementation TabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// 通过appearance统一设置UITabBarItem的文字属性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
attrs[NSForegroundColorAttributeName] = [UIColor grayColor];
NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
selectedAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
// 拿到UITabBarItem的appearance
UITabBarItem *item = [UITabBarItem appearance];
[item setTitleTextAttributes:attrs forState:UIControlStateNormal];
[item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
// 给tabBarController添加子控制器
[self setupChildVc:[[EssenceViewController alloc] init] title:@"精华" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
[self setupChildVc:[[NewViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
[self setupChildVc:[[FriendTrendsViewController alloc] init] title:@"关注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
[self setupChildVc:[[MeViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
// 更换为自定义的tabBar
// self.tabBar = [[TabBar alloc] init]; //tabBar为只读属性,所以我们下面采用KVC的方式
[self setValue:[[TabBar alloc] init] forKey:@"tabBar"];
}
/**
* 初始化子控制器
*/
- (void)setupChildVc:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage {
// 设置文字和图片
vc.tabBarItem.title = title;
vc.tabBarItem.image = [UIImage imageNamed:image];
vc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];
vc.view.backgroundColor = [UIColor colorWithRed:arc4random_uniform(100)/100.0 green:arc4random_uniform(100)/100.0 blue:arc4random_uniform(100)/100.0 alpha:1.0];
// 添加为子控制器
[self addChildViewController:vc];
}
@end
3.在自定义的UITabBar里,我们要创建一个特殊的按钮,然后要调整tabBar上所有UITabBarButton的布局
#import "TabBar.h"
@interface TabBar()
/** 发布按钮 */
@property(nonatomic,weak)UIButton *publishButton;
@end
@implementation TabBar
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
[publishButton setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
[publishButton setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
[self addSubview:publishButton];
self.publishButton = publishButton;
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
// 设置 发布按钮 的frame
self.publishButton.bounds = CGRectMake(0, 0, self.publishButton.currentBackgroundImage.size.width, self.publishButton.currentBackgroundImage.size.height);
self.publishButton.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);
// 设置其他UITabBarButton的frame
CGFloat buttonY = 0;
CGFloat buttonW = self.frame.size.width / 5;
CGFloat buttonH = self.frame.size.height;
NSInteger index = 0;
for (UIView *button in self.subviews) {
// 排除发布按钮
// if(![button isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue;
if(![button isKindOfClass:[UIControl class]] || button == self.publishButton) continue;
// 计算按钮的x值
CGFloat buttonX = buttonW * ((index>1) ? (index+1) : index);
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
// 增加索引
index++;
}
}
@end
最后效果: