轉載請標明出處:http://blog.csdn.net/android_ls/article/details/45896395android
聲明:仿新浪微博項目,所用全部圖片資源都來源於官方新浪微博IOS客戶端,編寫本應用的目的在於學習交流,如涉及侵權請告知,我會及時換掉用到的相關圖片。ide
自定義UITabBar替換系統默認的,目的是爲了在UITabBar中間位置添加一個「+號按鈕」,下面咱們來聊聊具體的實現。函數
一、自定義WBTabBar,讓其繼承自UITabBar,代碼以下:學習
// // WBTabBar.h // SinaWeibo // // Created by android_ls on 15/5/21. // Copyright (c) 2015年 android_ls. All rights reserved. // #import <UIKit/UIKit.h> @interface WBTabBar : UITabBar @end
二、tabBar是UITabBarController的只讀成員變量(屬性),是不讓修改的,在UITabBarController.h文件中的聲明以下:
ui
@property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0);
針對於這種狀況,咱們可使用KVC的方式,更換系統自帶的UITabBar,實現代碼以下:
atom
WBTabBar *tabBar = [[WBTabBar alloc] init]; [self setValue:tabBar forKeyPath:@"tabBar"];
三、添加一個UIButton到WBTabBar中,實現代碼以下:
spa
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 添加一個按鈕到tabbar中 UIButton *plusBtn = [[UIButton alloc] init]; [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal]; [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted]; [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateNormal]; [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted]; plusBtn.size = plusBtn.currentBackgroundImage.size; [plusBtn addTarget:self action:@selector(plusClick) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:plusBtn]; self.plusBtn = plusBtn; } return self; }
四、設置加號按鈕的位置,調整WBTabBar中各個UITabBarButton的位置和寬度,具體實現代碼以下:.net
- (void)layoutSubviews { [super layoutSubviews]; // 1.設置加號按鈕的位置 self.plusBtn.centerX = self.width * 0.5; self.plusBtn.centerY = self.height * 0.5; // 2.設置其它UITabBarButton的位置和尺寸 CGFloat tabbarButtonW = self.width / 5; CGFloat tabbarButtonIndex = 0; for (UIView *child in self.subviews) { Class class = NSClassFromString(@"UITabBarButton"); if ([child isKindOfClass:class]) { // 設置寬度 child.width = tabbarButtonW; // 設置x child.x = tabbarButtonIndex * tabbarButtonW; // 增長索引 tabbarButtonIndex++; if (tabbarButtonIndex == 2) { tabbarButtonIndex++; } } } }
五、定義WBTabBarDelegate協議,聲明WBTabBar的代理,代碼以下:代理
// // WBTabBar.h // SinaWeibo // // Created by android_ls on 15/5/21. // Copyright (c) 2015年 android_ls. All rights reserved. // #import <UIKit/UIKit.h> #pragma mark 由於在UITabBar中已經聲明過一個UITabBarDelegate協議, #pragma mark 咱們若想新增一個對外的代理函數,可讓咱們自定義的協議繼承自UITabBarDelegate,添加一個擴展函數。 @class WBTabBar; @protocol WBTabBarDelegate <UITabBarDelegate> @optional - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar; @end @interface WBTabBar : UITabBar @property (nonatomic, weak) id<WBTabBarDelegate> tabBarDelegate; @end
六、在加號按鈕的點擊事件處理器中,通知代理code
#pragma mark 加號按鈕點擊事件處理器 - (void)plusClick { // 通知代理 if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) { [self.tabBarDelegate tabBarDidClickPlusButton:self]; } }
七、在WBTabBarController中設置WBTabBar的代理,具體實現以下:
// 二、使用KVC的方式,更換系統自帶的UITabBar WBTabBar *tabBar = [[WBTabBar alloc] init]; tabBar.tabBarDelegate = self; [self setValue:tabBar forKeyPath:@"tabBar"];
#pragma mark - HWTabBarDelegate代理方法 - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar { ComposeViewController *composeViewController= [[ComposeViewController alloc] init]; UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:composeViewController]; [self presentViewController:navigationController animated:YES completion:nil]; }
八、有圖有真相,已實現的效果圖以下:
點擊加號按鈕,彈出寫做界面,效果圖以下:
WBTabBarController.m文件完整源碼以下:
// // WBTabBarController.m // SinaWeibo // // Created by android_ls on 15/5/17. // Copyright (c) 2015年 android_ls. All rights reserved. // #import "WBTabBarController.h" #import "HomeViewController.h" #import "MessageViewController.h" #import "DiscoverViewController.h" #import "ProfileViewController.h" #import "WBNavigationController.h" #import "WBTabBar.h" #import "ComposeViewController.h" @interface WBTabBarController ()<WBTabBarDelegate> { HomeViewController * _homeViewController; MessageViewController * _messageViewController; DiscoverViewController * _discoverViewController; ProfileViewController * _profileViewController; } @end @implementation WBTabBarController - (void)viewDidLoad { [super viewDidLoad]; // 初始化子控制器,並將其添加到UITabBarController中 _homeViewController = [[HomeViewController alloc]init]; [self addChildController:_homeViewController title:@"首頁" image:@"tabbar_home"]; _messageViewController = [[MessageViewController alloc]init]; [self addChildController:_messageViewController title:@"消息" image:@"tabbar_message_center"]; _discoverViewController = [[DiscoverViewController alloc]init]; [self addChildController:_discoverViewController title:@"發現" image:@"tabbar_discover"]; _profileViewController = [[ProfileViewController alloc]init]; [self addChildController:_profileViewController title:@"我" image:@"tabbar_profile"]; // @property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0); // tabBar是UITabBarController的只讀成員變量(屬性),是不讓修改的 // 二、使用KVC的方式,更換系統自帶的UITabBar WBTabBar *tabBar = [[WBTabBar alloc] init]; tabBar.tabBarDelegate = self; [self setValue:tabBar forKeyPath:@"tabBar"]; } #pragma mark - HWTabBarDelegate代理方法 - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar { ComposeViewController *composeViewController= [[ComposeViewController alloc] init]; UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:composeViewController]; [self presentViewController:navigationController animated:YES completion:nil]; } /** * 添加子控制器到UITabBarController中 */ - (void)addChildController:(UIViewController *)childViewController title:(NSString *)title image:(NSString *)image { // 設置子控制器,tabbar和navigationBar上的title childViewController.title = title; // 設置tabBarItem上默認的指示圖片和選中時的圖片 childViewController.tabBarItem.image = [UIImage imageNamed:image]; childViewController.tabBarItem.selectedImage = [[UIImage imageNamed:[NSString stringWithFormat:@"%@%@", image, @"_selected"]]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; // 設置tabBarItem上文字的樣式(這裏是設置文字在不一樣狀態下的顏色值) [childViewController.tabBarItem setTitleTextAttributes: @{NSForegroundColorAttributeName:kColor(117, 117, 117)} forState:UIControlStateNormal]; [childViewController.tabBarItem setTitleTextAttributes: @{NSForegroundColorAttributeName:kColor(253, 109, 10)} forState:UIControlStateSelected]; // 使用系統默認的UINavigationController // [self addChildViewController:[[UINavigationController alloc] initWithRootViewController:childViewController]]; // 使用咱們自定義的導航欄(WBNavigationController繼承自UINavigationController) WBNavigationController * navigationController = [[WBNavigationController alloc]initWithRootViewController:childViewController]; [self addChildViewController:navigationController]; } @end
WBTabBar.h文件完整源碼以下:
// // WBTabBar.h // SinaWeibo // // Created by android_ls on 15/5/21. // Copyright (c) 2015年 android_ls. All rights reserved. // #import <UIKit/UIKit.h> #pragma mark 由於在UITabBar中已經聲明過一個UITabBarDelegate協議, #pragma mark 咱們若想新增一個對外的代理函數,可讓咱們自定義的協議繼承自UITabBarDelegate,添加一個擴展函數。 @class WBTabBar; @protocol WBTabBarDelegate <UITabBarDelegate> @optional - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar; @end @interface WBTabBar : UITabBar @property (nonatomic, weak) id<WBTabBarDelegate> tabBarDelegate; @end
WBTabBar.m文件完整源碼以下:
// // WBTabBar.m // SinaWeibo // // Created by android_ls on 15/5/21. // Copyright (c) 2015年 android_ls. All rights reserved. // #import "WBTabBar.h" @interface WBTabBar() @property (nonatomic, weak) UIButton *plusBtn; @end @implementation WBTabBar - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 添加一個按鈕到tabbar中 UIButton *plusBtn = [[UIButton alloc] init]; [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal]; [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted]; [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateNormal]; [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted]; plusBtn.size = plusBtn.currentBackgroundImage.size; [plusBtn addTarget:self action:@selector(plusClick) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:plusBtn]; self.plusBtn = plusBtn; } return self; } #pragma mark 加號按鈕點擊事件處理器 - (void)plusClick { // 通知代理 if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) { [self.tabBarDelegate tabBarDidClickPlusButton:self]; } } - (void)layoutSubviews { [super layoutSubviews]; // 1.設置加號按鈕的位置 self.plusBtn.centerX = self.width * 0.5; self.plusBtn.centerY = self.height * 0.5; // 2.設置其它UITabBarButton的位置和尺寸 CGFloat tabbarButtonW = self.width / 5; CGFloat tabbarButtonIndex = 0; for (UIView *child in self.subviews) { Class class = NSClassFromString(@"UITabBarButton"); if ([child isKindOfClass:class]) { // 設置寬度 child.width = tabbarButtonW; // 設置x child.x = tabbarButtonIndex * tabbarButtonW; // 增長索引 tabbarButtonIndex++; if (tabbarButtonIndex == 2) { tabbarButtonIndex++; } } } } @end
ComposeViewController繼承自UIViewController,主要實如今m文件,其完整代碼以下:
// // ComposeViewController.m // SinaWeibo // // Created by android_ls on 15/5/21. // Copyright (c) 2015年 android_ls. All rights reserved. // #import "ComposeViewController.h" #import "UIBarButtonItem+Category.h" @interface ComposeViewController () @end @implementation ComposeViewController - (void)viewDidLoad { [super viewDidLoad]; self.title = @"寫做界面"; self.view.backgroundColor = [UIColor whiteColor]; self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"navigationbar_back_withtext" highImage:@"navigationbar_back_withtext_highlighted" title:@"返回"]; } - (void)back { [self.navigationController dismissViewControllerAnimated:YES completion:^{}]; } @end