iOS 用KVC來自定義Tabbar

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
  • 這樣我們的自定義tabbar就自定義好了,如果想看自定義的導航欄請看:iOS 導航欄的自定義,完美側滑返回
  • 如有錯誤,歡迎雅正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章