UITabBar自定義方式三(中間有按鈕)
阿新 • • 發佈:2019-01-01
1.MainTableViewController
#import "MainTabBarViewController.h" #import "IWHomeViewController.h" #import "IWMessageViewController.h" #import "IWMeViewController.h" #import "IWDiscoverViewController.h" #import "UIImage+MJ.h" #import "MyTabBar.h" @interface MainTabBarViewController () <IWTabBarDelegate> /** * 自定義的tabbar */ @property (nonatomic, weak) MyTabBar *customTabBar; @end @implementation MainTabBarViewController - (void)viewDidLoad { [super viewDidLoad]; // 初始化tabbar [self setupTabbar]; // 初始化所有的子控制器 [self setupAllChildViewControllers]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // 刪除系統自動生成的UITabBarButton for (UIView *child in self.tabBar.subviews) { if ([child isKindOfClass:[UIControl class]]) { [child removeFromSuperview]; } } } /** * 初始化tabbar */ - (void)setupTabbar { MyTabBar *customTabBar = [[MyTabBar alloc] init]; customTabBar.frame = self.tabBar.bounds; customTabBar.delegate = self; [self.tabBar addSubview:customTabBar]; self.customTabBar = customTabBar; } /** * 監聽tabbar按鈕的改變 * @param from 原來選中的位置 * @param to 最新選中的位置 */ - (void)tabBar:(MyTabBar *)tabBar didSelectedButtonFrom:(int)from to:(int)to { self.selectedIndex = to; } /** * 初始化所有的子控制器 */ - (void)setupAllChildViewControllers { // 1.首頁 IWHomeViewController *home = [[IWHomeViewController alloc] init]; [self setupChildViewController:home title:@"首頁" imageName:@"tabbar_home" selectedImageName:@"tabbar_home_selected"]; // 2.訊息 IWMessageViewController *message = [[IWMessageViewController alloc] init]; [self setupChildViewController:message title:@"訊息" imageName:@"tabbar_message_center" selectedImageName:@"tabbar_message_center_selected"]; // 3.廣場 IWDiscoverViewController *discover = [[IWDiscoverViewController alloc] init]; [self setupChildViewController:discover title:@"廣場" imageName:@"tabbar_discover" selectedImageName:@"tabbar_discover_selected"]; // 4.我 IWMeViewController *me = [[IWMeViewController alloc] init]; [self setupChildViewController:me title:@"我" imageName:@"tabbar_profile" selectedImageName:@"tabbar_profile_selected"]; } /** * 初始化一個子控制器 * * @param childVc 需要初始化的子控制器 * @param title 標題 * @param imageName 圖示 * @param selectedImageName 選中的圖示 */ - (void)setupChildViewController:(UIViewController *)childVc title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName { // 1.設定控制器的屬性 childVc.title = title; // 設定圖示 childVc.tabBarItem.image = [UIImage imageWithName:imageName]; // 設定選中的圖示 UIImage *selectedImage = [UIImage imageWithName:selectedImageName]; if (iOS7) { childVc.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; } else { childVc.tabBarItem.selectedImage = selectedImage; } // 2.包裝一個導航控制器 UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:childVc]; [self addChildViewController:nav]; // 3.新增tabbar內部的按鈕 [self.customTabBar addTabBarButtonWithItem:childVc.tabBarItem]; }
2.MyTabBar
3.MyTabBarButton#import <UIKit/UIKit.h> @class MyTabBar; @protocol IWTabBarDelegate <NSObject> @optional - (void)tabBar:(MyTabBar *)tabBar didSelectedButtonFrom:(int)from to:(int)to; @end @interface MyTabBar : UIView - (void)addTabBarButtonWithItem:(UITabBarItem *)item; @property (nonatomic, weak) id<IWTabBarDelegate> delegate; @end #import "MyTabBar.h" #import "MyTabBarButton.h" @interface MyTabBar() @property (nonatomic, strong) NSMutableArray *tabBarButtons; @property (nonatomic, weak) UIButton *plusButton; @property (nonatomic, weak) MyTabBarButton *selectedButton; @end @implementation MyTabBar - (NSMutableArray *)tabBarButtons { if (_tabBarButtons == nil) { _tabBarButtons = [NSMutableArray array]; } return _tabBarButtons; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { if (!iOS7) { // 非iOS7下,設定tabbar的背景 self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithName:@"tabbar_background"]]; } // 新增一個加號按鈕 UIButton *plusButton = [UIButton buttonWithType:UIButtonTypeCustom]; [plusButton setBackgroundImage:[UIImage imageWithName:@"tabbar_compose_button"] forState:UIControlStateNormal]; [plusButton setBackgroundImage:[UIImage imageWithName:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted]; [plusButton setImage:[UIImage imageWithName:@"tabbar_compose_icon_add"] forState:UIControlStateNormal]; [plusButton setImage:[UIImage imageWithName:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted]; plusButton.bounds = CGRectMake(0, 0, plusButton.currentBackgroundImage.size.width, plusButton.currentBackgroundImage.size.height); [self addSubview:plusButton]; self.plusButton = plusButton; } return self; } - (void)addTabBarButtonWithItem:(UITabBarItem *)item { // 1.建立按鈕 MyTabBarButton *button = [[MyTabBarButton alloc] init]; [self addSubview:button]; // 新增按鈕到陣列中 [self.tabBarButtons addObject:button]; // 2.設定資料 button.item = item; // 3.監聽按鈕點選 [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown]; // 4.預設選中第0個按鈕 if (self.tabBarButtons.count == 1) { [self buttonClick:button]; } } /** * 監聽按鈕點選 */ - (void)buttonClick:(MyTabBarButton *)button { // 1.通知代理 if ([self.delegate respondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) { [self.delegate tabBar:self didSelectedButtonFrom:self.selectedButton.tag to:button.tag]; } // 2.設定按鈕的狀態 self.selectedButton.selected = NO; button.selected = YES; self.selectedButton = button; } - (void)layoutSubviews { [super layoutSubviews]; // 調整加號按鈕的位置 CGFloat h = self.frame.size.height; CGFloat w = self.frame.size.width; self.plusButton.center = CGPointMake(w * 0.5, h * 0.5); // 按鈕的frame資料 CGFloat buttonH = h; CGFloat buttonW = w / self.subviews.count; CGFloat buttonY = 0; for (int index = 0; index<self.tabBarButtons.count; index++) { // 1.取出按鈕 MyTabBarButton *button = self.tabBarButtons[index]; // 2.設定按鈕的frame CGFloat buttonX = index * buttonW; if (index > 1) { buttonX += buttonW; } button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH); // 3.繫結tag button.tag = index; } } @end
#import <UIKit/UIKit.h> @interface MyTabBarButton : UIButton @property (nonatomic, strong) UITabBarItem *item; @end // 圖示的比例 #define IWTabBarButtonImageRatio 0.6 // 按鈕的預設文字顏色 #define IWTabBarButtonTitleColor (iOS7 ? [UIColor blackColor] : [UIColor whiteColor]) // 按鈕的選中文字顏色 #define IWTabBarButtonTitleSelectedColor (iOS7 ? IWColor(234, 103, 7) : IWColor(248, 139, 0)) #import "MyTabBarButton.h" #import "MyBadgeButton.h" @interface MyTabBarButton() /** * 提醒數字 */ @property (nonatomic, weak) MyBadgeButton *badgeButton; @end @implementation MyTabBarButton - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 圖示居中 self.imageView.contentMode = UIViewContentModeCenter; // 文字居中 self.titleLabel.textAlignment = NSTextAlignmentCenter; // 字型大小 self.titleLabel.font = [UIFont systemFontOfSize:11]; // 文字顏色 [self setTitleColor:IWTabBarButtonTitleColor forState:UIControlStateNormal]; [self setTitleColor:IWTabBarButtonTitleSelectedColor forState:UIControlStateSelected]; if (!iOS7) { // 非iOS7下,設定按鈕選中時的背景 [self setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected]; } // 新增一個提醒數字按鈕 MyBadgeButton *badgeButton = [[MyBadgeButton alloc] init]; badgeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; [self addSubview:badgeButton]; self.badgeButton = badgeButton; } return self; } // 重寫去掉高亮狀態 - (void)setHighlighted:(BOOL)highlighted {} // 內部圖片的frame - (CGRect)imageRectForContentRect:(CGRect)contentRect { CGFloat imageW = contentRect.size.width; CGFloat imageH = contentRect.size.height * IWTabBarButtonImageRatio; return CGRectMake(0, 0, imageW, imageH); } // 內部文字的frame - (CGRect)titleRectForContentRect:(CGRect)contentRect { CGFloat titleY = contentRect.size.height * IWTabBarButtonImageRatio; CGFloat titleW = contentRect.size.width; CGFloat titleH = contentRect.size.height - titleY; return CGRectMake(0, titleY, titleW, titleH); } // 設定item - (void)setItem:(UITabBarItem *)item { _item = item; // KVO 監聽屬性改變 [item addObserver:self forKeyPath:@"badgeValue" options:0 context:nil]; [item addObserver:self forKeyPath:@"title" options:0 context:nil]; [item addObserver:self forKeyPath:@"image" options:0 context:nil]; [item addObserver:self forKeyPath:@"selectedImage" options:0 context:nil]; [self observeValueForKeyPath:nil ofObject:nil change:nil context:nil]; } - (void)dealloc { [self.item removeObserver:self forKeyPath:@"badgeValue"]; [self.item removeObserver:self forKeyPath:@"title"]; [self.item removeObserver:self forKeyPath:@"image"]; [self.item removeObserver:self forKeyPath:@"selectedImage"]; } /** * 監聽到某個物件的屬性改變了,就會呼叫 * * @param keyPath 屬性名 * @param object 哪個物件的屬性被改變 * @param change 屬性發生的改變 */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // 設定文字 [self setTitle:self.item.title forState:UIControlStateSelected]; [self setTitle:self.item.title forState:UIControlStateNormal]; // 設定圖片 [self setImage:self.item.image forState:UIControlStateNormal]; [self setImage:self.item.selectedImage forState:UIControlStateSelected]; // 設定提醒數字 self.badgeButton.badgeValue = self.item.badgeValue; // 設定提醒數字的位置 CGFloat badgeY = 5; CGFloat badgeX = self.frame.size.width - self.badgeButton.frame.size.width - 10; CGRect badgeF = self.badgeButton.frame; badgeF.origin.x = badgeX; badgeF.origin.y = badgeY; self.badgeButton.frame = badgeF; } @end
4.MyBadgeButton提醒數字
@interface MyBadgeButton : UIButton
@property (nonatomic, copy) NSString *badgeValue;
@end
#import "MyBadgeButton.h"
@implementation MyBadgeButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.hidden = YES;
self.userInteractionEnabled = NO;
[self setBackgroundImage:[UIImage resizedImageWithName:@"main_badge"] forState:UIControlStateNormal];
self.titleLabel.font = [UIFont systemFontOfSize:11];
}
return self;
}
- (void)setBadgeValue:(NSString *)badgeValue
{
#warning copy
// _badgeValue = badgeValue;
_badgeValue = [badgeValue copy];
if (badgeValue) {
self.hidden = NO;
// 設定文字
[self setTitle:badgeValue forState:UIControlStateNormal];
// 設定frame
CGRect frame = self.frame;
CGFloat badgeH = self.currentBackgroundImage.size.height;
CGFloat badgeW = self.currentBackgroundImage.size.width;
if (badgeValue.length > 1) {
// 文字的尺寸
CGSize badgeSize = [badgeValue sizeWithFont:self.titleLabel.font];
badgeW = badgeSize.width + 10;
}
frame.size.width = badgeW;
frame.size.height = badgeH;
self.frame = frame;
} else {
self.hidden = YES;
}
}
@end
Demo連結: http://pan.baidu.com/s/1qW9RjA0 密碼: s22h