02.自定義tabBar

最終效果

1.tabBar 的基本信息設(shè)置

1.1 tabBarItem 的信息設(shè)置

UIViewController *vc = [[UIViewController alloc] init];
    vc.tabBarItem.title = @"標(biāo)題";
    vc.tabBarItem.image = [UIImage imageNamed:@"tabBar_new_icon"];
    vc.tabBarItem.selectedImage = [UIImage imageNamed:@"tabBar_new_click_icon"];
    vc.view.backgroundColor = [UIColor grayColor];

NSDictionary * attr = @{NSFont

AttributeName:[UIFont systemFontOfSize:12],NSForegroundColorAttributeName:[UIColor grayColor]};
    [vc.tabBarItem setTitleTextAttributes:attrs forState:UIControlStateNormal];
 NSDictionary * selectedAttrs = @{NSFontAttributeName:[UIFont systemFontOfSize:12],NSForegroundColorAttributeName:[UIColor darkGrayColor]};
    [vc.tabBarItem setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];

    [self addChildViewController:vc];

** 注意:**以上設(shè)置 tabBarItem 的 selectedImage 的方法,在實際運行過程中的效果與圖片本身的效果會有很大差異-----系統(tǒng)會默認(rèn)將選中圖片渲染成藍(lán)色展示

1.2 解決 tabBarItem 選中圖片渲染的問題

  • 代碼解決
    通過 UIImage的 imageWithRenderingMode 方法返回一個帶有渲染模式的圖片
- (UIImage *)imageWithRenderingMode:(UIImageRenderingMode)renderingMode ;

UIImageRenderingMode:
UIImageRenderingModeAutomatic  // 根據(jù)圖片的使用環(huán)境和所處的繪圖上下文自動調(diào)整渲染模式捅僵。  
UIImageRenderingModeAlwaysOriginal   // 始終繪制圖片原始狀態(tài)下硕,不使用Tint Color涝涤。  
UIImageRenderingModeAlwaysTemplate   // 始終根據(jù)Tint Color繪制圖片饰及,忽略圖片的顏色信息。  

UIImage *image = [UIImage imageNamed:imageName];
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
vc.tabBarItem.selectedImage = image;

代碼解決的缺陷:代碼量繁瑣植榕,當(dāng)圖片用在另一個地方處理渲染效果時還需要再次設(shè)置

  • 一次性設(shè)置---推薦使用
設(shè)置圖片渲染模式

1.3 appearance 設(shè)置文字屬性

在1.1的代碼中我們是通過下面方法粱腻,設(shè)置每一個item中文字的屬性的庇配。這種方法進行設(shè)置的話,需要對每一個item都進行設(shè)置栖疑,比較繁瑣

- (void)setTitleTextAttributes:(nullable NSDictionary<NSString *,id> *)attributes forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
  • UIAppearance:通過UIAppearance設(shè)置一些UI的全局效果---實現(xiàn)一改全改的效果
// 通過appearance統(tǒng)一設(shè)置所有UITabBarItem的文字屬性
// 后面帶有UI_APPEARANCE_SELECTOR的方法, 都可以通過appearance對象來統(tǒng)一設(shè)置
 [[UITabBarItem appearance] setTitleTextAttributes:attrs forState:UIControlStateNormal];
 [[UITabBarItem appearance] setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];

2.自定義tabBar

2.1自定義控制器

創(chuàng)建繼承于 UIViewController 的控制器----不再贅述

2.2自定義TabBarController

創(chuàng)建繼承于 UITabBarController 的控制器

@interface ZZYTabBarViewController ()

@end

@implementation ZZYTabBarViewController

+ (void)initialize
{
    //1讨永、設(shè)置UITabBarItem相關(guān)屬性
    NSDictionary * attrs = @{NSForegroundColorAttributeName:[UIColor grayColor],NSFontAttributeName:[UIFont systemFontOfSize:12]};
    NSDictionary * selectedAttrs = @{NSForegroundColorAttributeName:[UIColor darkGrayColor],NSFontAttributeName:[UIFont systemFontOfSize:12]};
   
   UITabBarItem * item = [UITabBarItem appearance];
    [item setTitleTextAttributes:attrs forState:UIControlStateNormal];
    [item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //2、初始化子控制器
    [self setupChildVc:[[ZZYEssenceViewController alloc] init] title:@"精華" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
    
    [self setupChildVc:[[ZZYNewViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
    
    [self setupChildVc:[[ZZYFriendTrendsViewController alloc] init] title:@"關(guān)注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
    
    [self setupChildVc:[[ZZYMeViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
    
    //3.自定義TabBar ----- 更換TabBar
    [self setValue:[[ZZYTabBar alloc]init] forKeyPath:@"tabBar"];
//    self.tabBar
}

- (void)setupChildVc:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
    // 設(shè)置文字和圖片
    vc.tabBarItem.title = title;
    vc.tabBarItem.image = [UIImage imageNamed:image];
    vc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];

    ZZYNavigationController * nav = [[ZZYNavigationController alloc]initWithRootViewController:vc];
    // 添加為子控制器
    [self addChildViewController:nav];

}

** 注意 :**

在設(shè)置自定義的 TabBar 時遇革,由于 tabBar 是系統(tǒng)默認(rèn) 只讀屬性卿闹,因此需要通過 KVC 語法揭糕,將自定義的 tabBar 對象,賦值給 tabBar 屬性即可

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
tabBar屬性

2.3 自定義TabBar

創(chuàng)建繼承于UITabBar 的 TabBar

#import "ZZYTabBar.h"

@interface ZZYTabBar()
/**
 *  發(fā)布按鈕
 */
@property (nonatomic, weak) UIButton * publishButton;

@end

@implementation ZZYTabBar

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        
        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];
    
    //設(shè)置發(fā)布按鈕的frame
注意此處設(shè)置 frame 時直接獲取 UIImage 對象寬高的方法
    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);
    
    // 設(shè)置其他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")])
        {
            //設(shè)置按鈕的x值---注意此處自定義的按鈕在中間锻霎,注意此處索引的處理
            CGFloat buttonX = buttonW * ((index > 1)?(index + 1):index);
            button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
            
            // 增加索引
            index++;
        }

    }
}

** 封裝控件基本步驟 **

  • 在 initWithFrame:方法中添加子控件著角,提供便利構(gòu)造方法
  • 在 layoutSubviews 方法中設(shè)置子控件的 frame(一定要調(diào)用 super 的 layoutSubviews )
  • 增加模型屬性,在模型屬性 set 方法中設(shè)置數(shù)據(jù)到子控件上

2.4 對 Frame 進行封裝

通過創(chuàng)建 UIView 的分類來方便對 view 的frame 中width height 屬性的設(shè)置

#import <UIKit/UIKit.h>

@interface UIView (ZZYExtension)

@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;

//- (CGFloat)x;
//- (void)setX:(CGFloat)x;
/** 在分類中聲明@property, 只會生成方法的聲明, 不會生成方法的實現(xiàn)和帶有_下劃線的成員變量*/

@end

#import "UIView+ZZYExtension.h"

@implementation UIView (ZZYExtension)

- (void)setWidth:(CGFloat)width
{
    CGRect frame = self.frame;
    frame.size.width = width;
    self.frame = frame;
}

- (void)setHeight:(CGFloat)height{
    CGRect frame = self.frame;
    frame.size. height = height;
    self.frame = frame;
}


- (void)setX:(CGFloat)x
{
    CGRect frame = self.frame;
    frame.origin.x = x;
    self.frame = frame;
}

- (void)setY:(CGFloat)y
{
    CGRect frame = self.frame;
    frame.origin.y = y;
    self.frame = frame;
}

- (CGFloat)width
{
    return self.frame.size.width;
}

- (CGFloat)height
{
    return self.frame.size.height;
}

- (CGFloat)x
{
    return self.frame.origin.x;
}

- (CGFloat)y
{
    return self.frame.origin.y;
}
@end

封裝后的按鈕 frame 設(shè)置代碼

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    CGFloat width = self.width;
    CGFloat height = self.height;
    
    //設(shè)置發(fā)布按鈕的frame
    self.publishButton.width = self.publishButton.currentBackgroundImage.size.width;
    self.publishButton.height = self.publishButton.currentBackgroundImage.size.height;
    
    self.publishButton.center = CGPointMake(width * 0.5, height * 0.5);
    
    // 設(shè)置其他UITabBarButton的frame
    CGFloat buttonY = 0;
    CGFloat buttonW = width / 5;
    CGFloat buttonH = height;
    NSInteger index = 0;

     //下面的與上面重復(fù)
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旋恼,一起剝皮案震驚了整個濱河市吏口,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冰更,老刑警劉巖产徊,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜀细,居然都是意外死亡舟铜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門奠衔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谆刨,“玉大人,你說我怎么就攤上這事归斤∪玻” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵脏里,是天一觀的道長她我。 經(jīng)常有香客問我,道長膝宁,這世上最難降的妖魔是什么鸦难? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任根吁,我火速辦了婚禮员淫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘击敌。我一直安慰自己介返,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布沃斤。 她就那樣靜靜地躺著圣蝎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衡瓶。 梳的紋絲不亂的頭發(fā)上徘公,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音哮针,去河邊找鬼关面。 笑死坦袍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的等太。 我是一名探鬼主播捂齐,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缩抡!你這毒婦竟也來了奠宜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瞻想,失蹤者是張志新(化名)和其女友劉穎压真,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蘑险,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡榴都,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了漠其。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘴高。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖和屎,靈堂內(nèi)的尸體忽然破棺而出拴驮,到底是詐尸還是另有隱情,我是刑警寧澤柴信,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布套啤,位于F島的核電站,受9級特大地震影響随常,放射性物質(zhì)發(fā)生泄漏潜沦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一绪氛、第九天 我趴在偏房一處隱蔽的房頂上張望唆鸡。 院中可真熱鬧,春花似錦枣察、人聲如沸争占。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臂痕。三九已至,卻和暖如春猿涨,著一層夾襖步出監(jiān)牢的瞬間握童,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工叛赚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澡绩,地道東北人片效。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像英古,于是被迫代替她去往敵國和親淀衣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫召调、插件膨桥、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,120評論 4 61
  • 前言 很多時候,系統(tǒng)原生的 UITabBar 并不能滿足我們的需求唠叛,譬如我們想要給圖標(biāo)做動態(tài)的改變只嚣,或者比較炫一點...
    四月_Hsu閱讀 5,054評論 1 6
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,286評論 25 707
  • 讀書是讓自己更加了解自己和外面的世界,讀書又有什么方法呢艺沼? 1.邊問邊讀 問自己有什么想知道或想解決的問題册舞,能提供...
    蕭雅琴子閱讀 281評論 0 0
  • 第一次見到主人時,我剛出生沒幾天障般。 那天上午我心情很好调鲸,我跟我的那群小伙伴們相互依偎在一起,陽光透過木箱照射進來挽荡,...
    蓋子團長閱讀 760評論 1 0