導(dǎo)航欄自定義 & 返回按鈕圖標(biāo)和文字 & 側(cè)滑失效問(wèn)題

前言

前段時(shí)間有個(gè)小伙伴想統(tǒng)一設(shè)置app導(dǎo)航欄返回按鈕的文字,但是用的方法是
[UINavigationBar appearance].backItem.title = @"返回";
來(lái)問(wèn)為什么沒起作用,其實(shí)是概念的不清晰,想當(dāng)然以為backItem是返回按鈕。故從蠻久以前的筆記里整理了這篇文章( [UINavigationBar appearance].backItem其實(shí)是nil )

基礎(chǔ)概念

62F192F1-9F82-48FE-9783-312E35E74D01.png

UINavigationBar管理?xiàng)I纤锌刂破鞯膎avigationItem(UINavigationItem)径密,保存在items屬性中,
topItem是棧頂?shù)膇tem,即對(duì)當(dāng)前頁(yè)面起作用item(當(dāng)前控制器中獲取self.navigationItem)

例:從A控制器push到了B控制器
B.navigationItem == B.navigationController.navigationBar.topItem
backItem是前一個(gè)控制器的navigationItem
即:A.navigationItem == B.navigationController.navigationBar.backItem

UINavigationItem繼承自NSObject,相當(dāng)于一個(gè)模型廷粒,
封裝了當(dāng)前導(dǎo)航bar上需要顯示的所有信息。
(包含title红且,titleView坝茎,backBarButtonItem(UIBarButtonItem),leftBarButtonItem(UIBarButtonItem)暇番,rightBarButtonItem(UIBarButtonItem)等屬性)

UIBarButtonItem是放在bar上的特殊的button嗤放,能處理點(diǎn)擊事件

UINavigationItem對(duì)象可設(shè)置多個(gè)UIBarButtonItem對(duì)象,
例控制器中設(shè)置 :
self.navigationItem.leftBarButtonItem;
self.navigationItem.rightBarButtonItem;

當(dāng)前控制器的navigationItem的backBarButtonItem決定下一個(gè)控制器的返回按鈕壁酬。
即設(shè)置A.navigationItem.backBarButtonItem次酌,實(shí)際上設(shè)置的是在B控制器中顯示默認(rèn)的返回按鈕


設(shè)置導(dǎo)航欄返回按鈕文字:

導(dǎo)航欄左側(cè)按鈕規(guī)則:

例:從A控制器 push到B控制器

  1. 如果B控制器有自定義的leftBarButtonItem,則顯示這個(gè)leftBarButtonItem;
  2. 如果B控制器沒有舆乔,看A控制器backBarButtonItem屬性是否有自定義項(xiàng)岳服,有則顯示;
  3. 12都沒有,則默認(rèn)顯示一個(gè)返回按鈕希俩,文字是A控制器的標(biāo)題吊宋。
方法一:
在B控制器中設(shè)置leftBarButtonItem。
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(back)];
self.navigationItem.leftBarButtonItem = leftItem;

注:如果給控制器添加了leftBarButtonItem颜武,系統(tǒng)側(cè)滑返回手勢(shì)會(huì)失效

方法二:
在A控制器中設(shè)置backBarButtonItem璃搜,實(shí)際上設(shè)置的就是B控制器上默認(rèn)顯示的返回按鈕
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];

**注:self.navigationItem.backBarButtonItem.title = @"返回”; 直接這樣設(shè)置無(wú)效,
title需要item設(shè)置到bar之前修改鳞上,而backBarButtonItem是系統(tǒng)內(nèi)置的摄职,所以直接改無(wú)效曲管,而且如果沒有手動(dòng)設(shè)置backBarButtonItem废登,獲取到的backBarButtonItem也是nil擎宝。

方法三:利用runtime一次設(shè)置全部控制器
1、建一個(gè)UIViewController分類
2、在分類的+load方法里用method swizzling來(lái)hook控制器的viewDidLoad方法
3趾断、同方法二統(tǒng)一設(shè)置 
文字設(shè)置為空的做法也可以設(shè)置為創(chuàng)建title是空字符串的UIBarButtonItem
網(wǎng)上也有做法是設(shè)置文字偏移到屏幕外:(據(jù)說(shuō)會(huì)有閃屏的可能拒名?)
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -100)
                                                     forBarMetrics:UIBarMetricsDefault];

統(tǒng)一設(shè)置導(dǎo)航欄返回按鈕圖片:

UIImage *buttonBackImg = [UIImage imageNamed:@"ic_navbar_back-black_normal”];
// 可以設(shè)置圖片不要渲染
// buttonBackImg = [buttonBackImg imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

[[UINavigationBar appearance] setBackIndicatorImage:buttonBackImg];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:buttonBackImg];

處理設(shè)置了leftBarButtonItem后側(cè)滑返回失效/控制器中scrollview與側(cè)滑共存問(wèn)題:

核心就是自定義一個(gè)導(dǎo)航控制器,并作為手勢(shì)對(duì)象的代理和導(dǎo)航控制器的代理芋酌,同時(shí)處理手勢(shì)沖突問(wèn)題

#import “NavViewController.h"

@interface NavViewController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>
@end
@implementation NavViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    __weak __typeof(self) weakSelf = self;
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    {
        // UIScreenEdgePanGestureRecognizer
        self.interactivePopGestureRecognizer.delegate = weakSelf;
        self.delegate = weakSelf;
    }
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
        self.interactivePopGestureRecognizer.enabled = NO;
   
    [super pushViewController:viewController animated:animated];
}


#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animate
{
    // Enable the gesture again once the new controller is shown
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
        self.interactivePopGestureRecognizer.enabled = YES;
}


#pragma mark UINavigationControllerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([self.childViewControllers count] == 1) {
        return NO;
    }
    return YES;
}

// ViewController接受多個(gè)手勢(shì)增显,再處理手勢(shì)沖突問(wèn)題。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

// 處理手指在滑動(dòng)的時(shí)候脐帝,被pop的 ViewController 中的 UIScrollView 會(huì)跟著一起滾動(dòng)問(wèn)題
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
}

@end


導(dǎo)航欄自定義

// 底部陰影
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
// 背景圖片
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];

//bar背景顏色
[[UINavigationBar appearance] setBarTintColor:[UIColor clearColor]];

// 文字顏色
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

// 標(biāo)題位置偏移
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:10 forBarMetrics:UIBarMetricsDefault];

// 標(biāo)題字體
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 0);
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                      [UIFont systemFontOfSize:16], NSFontAttributeName,
                                                       shadow,NSShadowAttributeName, nil]];
                                                       
// 返回圖標(biāo)
[UINavigationBar appearance].backIndicatorImage =
[UINavigationBar appearance].backIndicatorTransitionMaskImage =
[[UIImage imageNamed:@"ic_navbar_back-black_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末同云,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子堵腹,更是在濱河造成了極大的恐慌炸站,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疚顷,死亡現(xiàn)場(chǎng)離奇詭異旱易,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)腿堤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門阀坏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人笆檀,你說(shuō)我怎么就攤上這事忌堂。” “怎么了酗洒?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵士修,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我樱衷,道長(zhǎng)李命,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任箫老,我火速辦了婚禮,結(jié)果婚禮上黔州,老公的妹妹穿的比我還像新娘耍鬓。我一直安慰自己,他們只是感情好流妻,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布牲蜀。 她就那樣靜靜地躺著,像睡著了一般绅这。 火紅的嫁衣襯著肌膚如雪涣达。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音度苔,去河邊找鬼匆篓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寇窑,可吹牛的內(nèi)容都是我干的鸦概。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼甩骏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窗市!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起饮笛,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咨察,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后福青,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摄狱,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年素跺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了二蓝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡指厌,死狀恐怖刊愚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踩验,我是刑警寧澤鸥诽,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站箕憾,受9級(jí)特大地震影響牡借,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袭异,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一钠龙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧御铃,春花似錦碴里、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至睡互,卻和暖如春根竿,著一層夾襖步出監(jiān)牢的瞬間陵像,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工寇壳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留醒颖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓九巡,卻偏偏與公主長(zhǎng)得像图贸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冕广,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

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