iOS 更改導(dǎo)航欄背景顏色&透明度

弄了一年多的微信小程序一罩,終于又回到iOS了廊驼,廢話不多說犹芹,進(jìn)入正題:

&更改導(dǎo)航欄背景顏色

首先來說更改導(dǎo)航欄顏色的方式有很多熙涤,比如自定義一個導(dǎo)航欄阁苞,但是這樣就會破壞掉系統(tǒng)導(dǎo)航欄的功能(比如側(cè)滑返回)而且也失去了系統(tǒng)導(dǎo)航欄的平滑過渡困檩。

相對于自定義,我們也可以更改系統(tǒng)的導(dǎo)航欄顏色那槽,比較簡單的方式是悼沿,直接設(shè)置導(dǎo)航欄的tintColor 如下:

self.navigationController.navigationBar.barTintColor = [UIColor redColor];

這種方法可以很大程度上實(shí)現(xiàn)導(dǎo)航欄顏色渲染,但是美中不足的是骚灸,這樣渲染出來的顏色和實(shí)際顏色會有一丁點(diǎn)的色差糟趾,若果對設(shè)計(jì)的要求不高,這個方法完全可以行得通甚牲。

接下來我們來介紹一個略微麻煩的方式义郑,雖然麻煩,但是為了程序員通有的強(qiáng)迫癥丈钙,這點(diǎn)麻煩還是值得的

其原理很簡單非驮,首先找到導(dǎo)航欄的底視圖,并在該視圖上插入一層我們自定義的視圖(也許有人會問都找到底視圖了著恩,為什么還要插入自己的視圖院尔,直接用底視圖不就得了,這個問題很好回答喉誊,樓主任性)

對于這種麻煩而又常用的東西邀摆,我們首先會想到把他單獨(dú)拿出來寫到一個類里,這里也不例外伍茄,我們先創(chuàng)建一個 UINavigationBar 的分類栋盹,姑且叫做(handle)然后在里面添加一個方法 如下:

#import <UIKit/UIKit.h>

@interface UINavigationBar (handle)
/**
 更改導(dǎo)航欄顏色和圖片

 @param color 顏色
 @param barImage 圖片
 */
- (void)navBarBackGroundColor:(UIColor *_Nullable)color image:(UIImage *_Nullable)barImage;
@end

看到這個方法名,你一定已經(jīng)知道它的作用了敷矫,當(dāng)然光有名字肯定不行例获,那我們就去.m文件里實(shí)現(xiàn)它,首先在.m文件中導(dǎo)入runtime頭文件添加該分類的匿名類別 如下:

#import "UINavigationBar+handle.h"
#import <objc/runtime.h>

@interface UINavigationBar()
@property (nonatomic, strong) UIImage       *backClearImage;
@property (nonatomic, strong) UIImage       *lineClearImage;
@property (nonatomic, strong) MyNavLayer    *myLayer; //自定義插入層曹仗,自定義操作都要在這一層上進(jìn)行

@implementation UINavigationBar (handle)
- (void)navBarBackGroundColor:(UIColor *)color image:(UIImage *)barImage {
  ...
}
@end

由于是在分類中榨汤,由于分類中無法建立變量,所以所用到的屬性需要runtime 關(guān)聯(lián)一下怎茫,方法去看我的demo
接下來我們來實(shí)現(xiàn)這個更改顏色和背景圖片的方法

1收壕,使用kvc找到navigationbar的底視圖 如下:
UIView *backView = [self valueForKey:@"backgroundView"];
2,因?yàn)槲覀円迦胱约憾x的圖層轨蛤,所以我們要先把原來導(dǎo)航欄的特征去掉(這里不是去掉導(dǎo)航欄蜜宪,而是把其透明處理),方法很簡單祥山,只需要用一個空的image去填充原來的背景 如下:透明化背景圃验,透明化底線
//通過插入空image把背景變透明
    if (!self.backClearImage) {
        self.backClearImage = [[UIImage alloc]init];
        [self setBackgroundImage:self.backClearImage
                   forBarMetrics:UIBarMetricsDefault];
        self.barStyle = UIBarStyleBlackOpaque;
    }
    //去掉系統(tǒng)底線,使用自定義底線
    if (!self.lineClearImage) {
        self.lineClearImage = [[UIImage alloc]init];
        [self setShadowImage:self.lineClearImage];
    }

*題外話:說道這里我們說一下為什么樓主不用原底層視圖缝呕,而是要自定義一個澳窑,首先直接在backView上進(jìn)行更是不行的斧散,該底視圖的屬性是無法更的,比如(backView.backGroundColor = [UIColor redColor] ;)無效照捡,如果還想實(shí)現(xiàn)背景的更改颅湘,就要從這個空image入手,首先準(zhǔn)備一個1x1的帶顏色的圖片(當(dāng)然如果顏色不固定也可以通過drawrect畫一張自定義顏色的視圖然后轉(zhuǎn)成image)然后用該image去填充原來的背景image就可以實(shí)現(xiàn)背景顏色的變換了栗精,大家可能看出來了闯参,這非常的不靈活,所以樓主也不是很任性悲立,對吧鹿寨。

好了,回到正題:
第三步就很簡單了薪夕,前面視圖已經(jīng)找到了脚草,而且也完成了元導(dǎo)航欄的透明處理,接下來我們只需要把自己的視圖的插入到底視圖上就OK了

導(dǎo)航欄的高度 = navigationBar的高度 + 狀態(tài)欄的高度

因?yàn)槭莕avigationBar的分類 所以navigationBar的高度:

CGFloat barHeight = self.bounds.size.height;

狀態(tài)欄高度:

CGFloat statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height;

完整代碼如下(myLayer為自定義導(dǎo)航欄層原献,繼承自calayer):

if (!self.myLayer) {
        //狀態(tài)欄高度
        CGFloat statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
        //導(dǎo)航欄高度
        CGFloat barHeight = self.bounds.size.height;
        CGRect barBounds = self.bounds;
        barBounds.size.height = statusHeight + barHeight;
        self.myLayer = [[MyNavLayer alloc]initWithFrame:barBounds];
    }
    
    if (color) {
        self.myLayer.backColor = color;
    }
    
    if (barImage) {
        self.myLayer.backImage = barImage;
    }
    
    //通過kvc找到系統(tǒng)導(dǎo)航欄背景層馏慨,把自定義層添加到背景層
    [[[self valueForKey:@"backgroundView"] layer] addSublayer:self.myLayer];

以上便是更改顏色的方法,使用時導(dǎo)入該分類如下:

#import "ViewController.h"
#import "UINavigationBar+handle.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"紅色導(dǎo)航欄";
    [self.navigationController.navigationBar navBarBackGroundColor:[UIColor redColor] image:nil];//顏色
}

&更改導(dǎo)航欄透明度

有了上面的鋪墊姑隅,透明應(yīng)該不在話下了写隶,原理和改背景顏色一樣,自定義視圖讲仰,然后更改自定義視圖的透明度

重復(fù)的東西這里就不贅述了慕趴,直接貼出更改方法和實(shí)現(xiàn):

#import <UIKit/UIKit.h>

@interface UINavigationBar (handle)
/**
 更改導(dǎo)航欄顏色和圖片

 @param color 顏色
 @param barImage 圖片
 */
- (void)navBarBackGroundColor:(UIColor *_Nullable)color image:(UIImage *_Nullable)barImage;

/**
 更改透明度

 @param alpha 導(dǎo)航欄透明度
 */
- (void)navBarAlpha:(CGFloat)alpha;
@end

方法實(shí)現(xiàn):

if (!self.myLayer) {
        //狀態(tài)欄高度
        CGFloat statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
        //導(dǎo)航欄高度
        CGFloat barHeight = self.bounds.size.height;
        CGRect barBounds = self.bounds;
        barBounds.size.height = statusHeight + barHeight;
        self.myLayer = [[MyNavLayer alloc]initWithFrame:barBounds];
    }
    
    self.myLayer.alpha = alpha;
    
    //通過kvc找到系統(tǒng)導(dǎo)航欄背景層,把自定義層添加到背景層
    [[[self valueForKey:@"backgroundView"] layer] addSublayer:self.myLayer];

好了鄙陡,到這里就完成了冕房,這里的代碼只是原理,需要的話直接去下載趁矾,然后把分類UINavigationBar+handle放到自己的項(xiàng)目里就OK了

為了換一句辛苦耙册,樓主花了一上午。
https://github.com/Xiexingda/NavBarHandle.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毫捣,一起剝皮案震驚了整個濱河市详拙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌培漏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胡本,死亡現(xiàn)場離奇詭異牌柄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)侧甫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門珊佣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹋宦,“玉大人,你說我怎么就攤上這事咒锻±淙撸” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵惑艇,是天一觀的道長蒿辙。 經(jīng)常有香客問我,道長滨巴,這世上最難降的妖魔是什么思灌? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮恭取,結(jié)果婚禮上泰偿,老公的妹妹穿的比我還像新娘。我一直安慰自己蜈垮,他們只是感情好耗跛,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著攒发,像睡著了一般调塌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晨继,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天烟阐,我揣著相機(jī)與錄音,去河邊找鬼紊扬。 笑死蜒茄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的餐屎。 我是一名探鬼主播檀葛,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腹缩!你這毒婦竟也來了屿聋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤藏鹊,失蹤者是張志新(化名)和其女友劉穎润讥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盘寡,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡楚殿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了竿痰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脆粥。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡砌溺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出变隔,到底是詐尸還是另有隱情规伐,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布匣缘,位于F島的核電站猖闪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏孵户。R本人自食惡果不足惜萧朝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夏哭。 院中可真熱鬧检柬,春花似錦、人聲如沸竖配。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽进胯。三九已至用爪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胁镐,已是汗流浹背偎血。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盯漂,地道東北人颇玷。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像就缆,于是被迫代替她去往敵國和親帖渠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

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

  • 前言 在開發(fā)過程中,經(jīng)常會碰到控制器對應(yīng)的導(dǎo)航欄的背景顏色不一致或者需要讓導(dǎo)航欄背景透明的需求切揭。在導(dǎo)航控制器pus...
    漸z閱讀 2,842評論 0 8
  • 用到的組件 1狞甚、通過CocoaPods安裝 2、第三方類庫安裝 3廓旬、第三方服務(wù) 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,602評論 1 180
  • 四月 四月是憂郁的哼审,從這走到那 整個季節(jié)被雨浸透 錯落的房屋緊挨彼此卻又不認(rèn)識 空氣是一堵墻,在四月 隔斷你我...
    吳曉彬閱讀 280評論 0 0
  • 陳青在鐵道左,顧頁在鐵道右巩步。 “陳青旁赊,陳青∫我埃”顧頁喚陳青终畅。 “我得回去了【股粒” “家里來信离福,我媽病了×陡颍” “我找好了...
    萬般柔情閱讀 267評論 0 3
  • 文 | 壹夢說專欄作者:王了個斑馬 周末的清晨八點(diǎn)鐘,日光漸強(qiáng)嗽上,蟬鳴潛伏在夏意里次舌,等待正午喧囂而起。赤腳從臥室遛進(jìn)...
    壹夢說閱讀 381評論 0 0