iOS 用KVC來自定義Tabbar

開發是一個學習的過程,當你在項目中遇到難點的時候,第一個想到的應該是Google,百度...我總是拿這樣一句話來形容自己,逆水行舟,不進則退,每時每刻都要學習,活到老,學到老.

1.首先看個例子,看下今天我們要自定義的這個tabbar.
tabbar.png

這種tabbar在很多應用中都有,最最常見的就是新浪微博,那這樣的我們該怎么做呢,不要著急慢慢來,我接下來采用的方法是利用系統的tabbar來自定義tabbar.

2.話不多說上代碼
  • 首先創建一個集成與UITabBarController的控制器,以下我們把他成為XTTabBarController,讓大家更好明白.
  • 還要創建好其余四個空的控制器.
  • XTTabBarController中,先來做一些我們大家都熟悉的設置
//先對tabbar做一些屬性設置.這個initialize方法,只會走一次,所以我們把tabbar初始化的一些方法放在這里面
+(void)initialize{
    //通過apperance統一設置UITabBarItem的文字屬性
    //后面帶有UI_APPEARANCE_SELECTOR的方法, 都可以通過appearance對象來統一設置
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
    attrs[NSForegroundColorAttributeName] = [UIColor grayColor];
    
    NSMutableDictionary *selectedAtts = [NSMutableDictionary dictionary];
    selectedAtts[NSFontAttributeName] = [UIFont systemFontOfSize:12];
    selectedAtts[NSForegroundColorAttributeName] = [UIColor grayColor];

    UITabBarItem *item = [UITabBarItem appearance];
    [item setTitleTextAttributes:attrs forState:UIControlStateNormal];
    [item setTitleTextAttributes:selectedAtts forState:UIControlStateSelected];
}
  • 然后添加子控制器(以下的方法都是我們經常用到的,我就不多做解釋了)
-(void)viewDidLoad {
    [super viewDidLoad];
      // 添加子控制器
    [self setupChildVc:[[XTEssenceViewController alloc] init] title:@"精華" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
    
    [self setupChildVc:[[XTNewViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
    
    [self setupChildVc:[[XTFriendTrendsViewController alloc] init] title:@"關注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
    
    [self setupChildVc:[[XTMeViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
}
-(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];
    UINavigationController *navVc = [[UINavigationController alloc]initWithRootViewController:vc];
    [self addChildViewController:navVc];
}
  • 通過以上的設置現在我們的tabbar是這樣的


    tabbar.png

    這是正常的tabbar,但是要再增加中間的那個按鈕該如何做能?接下來的就是重點

  • 通過KVC的方式來獲取系統的tabbar然后對系統的tabbar進行自定義,如果有些人對KVC不是很了解,可以看我之前寫過的一遍對KVC的博客,大家可以去看看:iOS KVC簡單理解
    自定義一個UITabBar,我們以下稱為XTTabBar,然后用XTTabBar來替換系統的tabbar,因為系統的tabbar是readonly的,所以我們只能通過KVC的方式來替換.
@property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0); .
//替換tabbar
-(void)viewDidLoad {
    [super viewDidLoad];
      // 添加子控制器
    [self setupChildVc:[[XTEssenceViewController alloc] init] title:@"精華" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
    
    [self setupChildVc:[[XTNewViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
    
    [self setupChildVc:[[XTFriendTrendsViewController alloc] init] title:@"關注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
    
    [self setupChildVc:[[XTMeViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];

    //跟換tabbar(KVC)   這里是關鍵
    XTTabBar *tabbar = [[XTTabBar alloc]init];
    [self setValue:tabbar forKeyPath:@"tabBar"];
}```

- 這樣我們就只需要在自定義的`XTTabBar`中去做一些操作了

//先初始化中間的那個按鈕
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self setBackgroundImage:[UIImage imageNamed:@"tabbar-light"]];
UIButton *publishButton = [[UIButton alloc]init];
[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;
}

//設置tabbar上按鈕的Frame
-(void)layoutSubviews{
[super layoutSubviews];

//設置其他tabbar的frame
CGFloat buttonY = 0;
CGFloat buttonW = self.width / 5;
CGFloat buttonH = self.height;

int index = 0;
for (UIView *button in self.subviews) {
    
    if (![button isKindOfClass:NSClassFromString(@"UITabBarButton")])continue;
        // 計算按鈕的x值
        CGFloat buttonX = buttonW * ((index > 1)?(index + 1):index);
        button.frame = CGRectMake( buttonX, buttonY, buttonW, buttonH);
        index++;
}

self.publishButton.size = self.publishButton.currentBackgroundImage.size;
self.publishButton.frame = CGRectMake(0, 0, self.publishButton.width,self.publishButton.height);
self.publishButton.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);

}

- 在這里我做一個補充,當我們去打印tabbar.subviews的時候,我們發現,在他的子視圖中有`UITabBarButton`,這樣一個類,但是我們找不到這個類.我們做的就是,把這4個`UITabBarButton`找出來,然后在給他們重新設置Frame.這就是為什么我上面的代碼中去遍歷他的子視圖了.
![tabbar.subviews.png](http://upload-images.jianshu.io/upload_images/1656986-753b74d006642f19.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- ######這樣我們的自定義tabbar就自定義好了,如果想看自定義的導航欄請看:[iOS 導航欄的自定義,完美側滑返回](http://www.lxweimin.com/p/2d544bfd3e9c)

- ####如有錯誤,歡迎雅正
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容