iOS導(dǎo)航欄隱藏透明處理 && 側(cè)滑返回手勢(shì)

1: 導(dǎo)航欄隱藏之間跳轉(zhuǎn) & 導(dǎo)航欄隱藏后顯示自定義導(dǎo)航欄
(由于系統(tǒng)導(dǎo)航欄透明造成的動(dòng)畫問題 暫時(shí)還未找到好的辦法童芹,目前都是采用隱藏 添加自定義導(dǎo)航欄谈截。

之前對(duì)于導(dǎo)航欄隱藏和透明的VC 绎晃,采用了一個(gè)封裝的導(dǎo)航欄VIew 但是需要單獨(dú)初始化丢早,顯的麻煩肴甸,
因?yàn)殡[藏的導(dǎo)航欄相嵌,大部分都還是需要一個(gè)導(dǎo)航條的屎暇,只是樣式跟整體風(fēng)格不同承桥,因此也將這個(gè)自定的導(dǎo)航條 改為 runtime 方式,

iOS導(dǎo)航欄對(duì)于隱藏造成的動(dòng)畫 可以通過在viewWillAppear和viewWillDisappear 來設(shè)置完成

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
     [self.navigationController setNavigationBarHidden:NO animated:animated];
}

但是對(duì)于多級(jí)跳轉(zhuǎn)的則不行根悼,之前一開始 自己采用的是繼承,但是繼承不是對(duì)于整個(gè)項(xiàng)目所適用的凶异,而實(shí)際中繼承的獨(dú)特,也只是為了判斷當(dāng)前控制器 是否需要隱藏導(dǎo)航欄挤巡,之前一開始是通過類型的方式判斷的剩彬,

+ (BOOL)naviIsHiddenWithVC: (UIViewController *)vc {
    if ([vc isKindOfClass:[NaviHiddenController class]]) {
        return YES;
    }
    return NO;
}

這樣的判斷 實(shí)際只需要通過caretory添加一個(gè)屬性或者方法即可達(dá)到同樣效果 判斷出是否需要隱藏。

具體代碼:

1矿卑、我采用的是用實(shí)例方法 來標(biāo)識(shí) 是否需要隱藏(也可以改為實(shí)例對(duì)象喉恋,調(diào)用的方式)

// 用于判斷當(dāng)前控制器是否需要隱藏導(dǎo)航欄 默認(rèn)不需要隱藏 需要隱藏的控制器 只需要重寫即可
- (BOOL)wyj_naviBarIsHidden {
    return NO;
}

2、交換方法

#pragma mark - 交換相關(guān)方法 ,也是為了在
+ (void)load {
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(viewWillAppear:)),
                                   class_getInstanceMethod(self, @selector(wyjBarHidden_viewWillAppear:)));
    
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(viewWillDisappear:)),
                                   class_getInstanceMethod(self, @selector(wyjBarHidden_viewWillDisappear:)));
   
 
    // 用于設(shè)置自定義導(dǎo)航欄View的
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(viewDidLoad)),
                                   class_getInstanceMethod(self, @selector(wyjBarHidden_viewDidLoad)));
    
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(setTitle:)),
                                   class_getInstanceMethod(self, @selector(wyjBarHidden_setTitle:)));
}

3轻黑、主要是push或者pop前后 的VC是否隱藏糊肤,判斷對(duì)才能確保相互跳轉(zhuǎn)之間的動(dòng)畫不會(huì)出問題

#pragma mark - super
- (void)wyjBarHidden_viewWillAppear:(BOOL)animated {
    [self wyjBarHidden_viewWillAppear:animated];
    
    if ([self wyj_naviBarIsHidden]) {
        [self.navigationController setNavigationBarHidden:YES animated:animated];
    }

// 用于自定義導(dǎo)航欄的
    [self.view bringSubviewToFront:self.wyj_naviView];
}

- (void)wyjBarHidden_viewWillDisappear:(BOOL)animated {
    [self wyjBarHidden_viewWillDisappear:animated];
    
    if ([self wyj_naviBarIsHidden] == NO) {
        return;
    }
    
    int pushNext = [self pushNextOrPop];
    // push下一個(gè)
    if (pushNext == 1) {
        if (NO == [self viewControllersPushIsHidden]) {
            [self.navigationController setNavigationBarHidden:NO animated:animated];
        }
        return;
    }
    // not Push
    if (NO == [self viewControllersPopIsHidden]) {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }
}

// push : 1
// pop  : 0
- (int)pushNextOrPop {
    NSArray *viewControllers = self.navigationController.viewControllers;
    if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
        return 1; // push
    }
    return 0;
}

// 此處判斷是否時(shí)隱藏的控制器 需要判斷涉及的相關(guān)類 
// push下一個(gè) 是不是隱藏
- (BOOL)viewControllersPushIsHidden {
    NSArray *viewControllers = self.navigationController.viewControllers;
    UIViewController *vc = [viewControllers objectAtIndex:viewControllers.count-1];
    return [vc wyj_naviBarIsHidden];
}

// pop last上一個(gè)
- (BOOL)viewControllersPopIsHidden {
    NSArray *viewControllers = self.navigationController.viewControllers;
    UIViewController *vc = [viewControllers objectAtIndex:viewControllers.count-1];
    return [vc wyj_naviBarIsHidden];
}

下面是添加的自定義導(dǎo)航欄的

1、有一個(gè)保存導(dǎo)航View的對(duì)象氓鄙,懶加載
2馆揉、在viewDidLoad中 添加,所以需要runtime交換方法抖拦,
3升酣、在viewWIllAppear中 將自定義導(dǎo)航顯示在最前面
4、由于title的時(shí)機(jī)不確定态罪,所以在重寫title噩茄,在使用的可以對(duì)title顯示,這樣對(duì)于一些需要導(dǎo)航欄透明的 只需要實(shí)現(xiàn)隱藏導(dǎo)航欄方法即可复颈,不需要在寫任何代碼

// ================== 添加默認(rèn)需要的自定義導(dǎo)航欄  ========================
#pragma mark - 添加默認(rèn)需要的自定義導(dǎo)航欄
- (void)wyjBarHidden_viewDidLoad {
    [self wyjBarHidden_viewDidLoad];
    
    [self.view addSubview:self.wyj_naviView];
}

- (void)wyjBarHidden_setTitle:(NSString *)title {
    [self wyjBarHidden_setTitle:title];
    
    self.wyj_naviView.titleLabel.text = title;
}

#pragma mark get set wyj_naviView

- (NavigationImitateView *)wyj_naviView {
    if (objc_getAssociatedObject(self, _cmd) == nil) {
        if ([self wyj_naviBarIsHidden]) {
            [self wyj_NaviViewInit];
        }
    }
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setWyj_naviView:(NavigationImitateView *)wyj_naviView {
    objc_setAssociatedObject(self, @selector(wyj_naviView), wyj_naviView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)wyj_naviBackAction {
    [self.navigationController popViewControllerAnimated:YES];
}
- (void)wyj_NaviViewInit {
    NavigationImitateView *view = [NavigationImitateView initDefaule];
    view.titleLabel.text = self.title;
    [view.leftButton addTarget:self action:@selector(wyj_naviBackAction) forControlEvents:(UIControlEventTouchUpInside)];
    self.wyj_naviView = view;
}

側(cè)滑返回手勢(shì)

在上面隱藏導(dǎo)航欄后 巢墅,系統(tǒng)的側(cè)滑返回手勢(shì)就失效了,因此我們添加一個(gè)側(cè)滑返回手勢(shì)
因?yàn)槲业膶?dǎo)航欄是統(tǒng)一繼承的券膀,所以我是在導(dǎo)航欄的基類里面寫的君纫,畢竟項(xiàng)目中 導(dǎo)航就tabbar那么幾個(gè)

添加自定義導(dǎo)航欄 ,并禁止系統(tǒng)的

- (void)setCustomGestureRecognizer {
    // 獲取系統(tǒng)自帶滑動(dòng)手勢(shì)的target對(duì)象
    id target = self.interactivePopGestureRecognizer.delegate;
    
    // 創(chuàng)建全屏滑動(dòng)手勢(shì)芹彬,調(diào)用系統(tǒng)自帶滑動(dòng)手勢(shì)的target的action方法
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
    
    // 設(shè)置手勢(shì)代理蓄髓,攔截手勢(shì)觸發(fā)
    pan.delegate = self;
    
    // 給導(dǎo)航控制器的view添加全屏滑動(dòng)手勢(shì)
    [self.view addGestureRecognizer:pan];
    
    // 禁止使用系統(tǒng)自帶的滑動(dòng)手勢(shì)
    self.interactivePopGestureRecognizer.enabled = NO;
}

然后在代理中 處理手勢(shì)在有效條件下才能有效

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // 注意:只有非根控制器才有滑動(dòng)返回功能,根控制器沒有舒帮。
    // 判斷導(dǎo)航控制器是否只有一個(gè)子控制器会喝,如果只有一個(gè)子控制器邪狞,肯定是根控制器
    if (self.childViewControllers.count == 1) {
        // 表示用戶在根控制器界面浸赫,就不需要觸發(fā)滑動(dòng)手勢(shì),
        return NO;
    }
    
    // 判斷當(dāng)前是否禁止側(cè)滑返回惰匙,
    UIViewController *topViewController = self.childViewControllers.lastObject;
    if ([topViewController wyj_naviPopGRDisable]) {
        return NO;
    }
    
// ---------------------- return YES------------------------------
//如果在此處 return YES ,則是全屏側(cè)滑返回
#  需要注意的是:
#    全屏返回手勢(shì)译红,會(huì)和 系統(tǒng)tabbarCell 左滑刪除的時(shí)候 手勢(shì)沖突预茄,導(dǎo)致左滑刪除不出來,
#    簡(jiǎn)單點(diǎn)我是將當(dāng)前手勢(shì)改為 左滑邊緣處 才能夠觸發(fā)侦厚,基本和系統(tǒng)的一樣
    CGPoint location = [gestureRecognizer locationInView:self.view];
    CGPoint offSet   = [gestureRecognizer locationInView:gestureRecognizer.view];
    BOOL    result   = (0 < offSet.x && location.x <= 40);
    return result;
    
//    return YES;
}

如果想要全屏側(cè)滑返回手勢(shì) 和 tableViewCell 左滑手勢(shì)共存耻陕,則需要提供額外接口,因?yàn)樾枰獙蓚€(gè)的代理結(jié)合刨沦,判斷需要如何處理哪個(gè)優(yōu)先級(jí)诗宣,此處用上述交簡(jiǎn)單的, 也算是模仿系統(tǒng)的方式處理

具體代碼我已經(jīng)抽出來
//使用的時(shí)候 只需要引入 #import "WYJNavigation.h"

//---------需要隱藏導(dǎo)航欄的文件  -----------
// 重寫
- (BOOL)wyj_naviBarIsHidden {
    return YES;
}
//---------需要添加左側(cè)滑動(dòng)返回的 -----------
讓根導(dǎo)航繼承 WYJNavigationController

文件下載:
鏈接: https://pan.baidu.com/s/1wdUN5Wa7jvgDcfiH0GTMgA 密碼: 73un

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末想诅,一起剝皮案震驚了整個(gè)濱河市召庞,隨后出現(xiàn)的幾起案子岛心,更是在濱河造成了極大的恐慌,老刑警劉巖篮灼,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹉梨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡穿稳,警方通過查閱死者的電腦和手機(jī)存皂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逢艘,“玉大人旦袋,你說我怎么就攤上這事∷模” “怎么了疤孕?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)央拖。 經(jīng)常有香客問我祭阀,道長(zhǎng),這世上最難降的妖魔是什么鲜戒? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任专控,我火速辦了婚禮,結(jié)果婚禮上遏餐,老公的妹妹穿的比我還像新娘伦腐。我一直安慰自己,他們只是感情好失都,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布柏蘑。 她就那樣靜靜地躺著,像睡著了一般粹庞。 火紅的嫁衣襯著肌膚如雪咳焚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天庞溜,我揣著相機(jī)與錄音革半,去河邊找鬼。 笑死强缘,一個(gè)胖子當(dāng)著我的面吹牛督惰,可吹牛的內(nèi)容都是我干的不傅。 我是一名探鬼主播旅掂,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼访娶!你這毒婦竟也來了商虐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秘车,沒想到半個(gè)月后典勇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叮趴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年割笙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眯亦。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伤溉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妻率,到底是詐尸還是另有隱情乱顾,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布宫静,位于F島的核電站走净,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏孤里。R本人自食惡果不足惜伏伯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捌袜。 院中可真熱鬧舵鳞,春花似錦、人聲如沸琢蛤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽博其。三九已至套才,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慕淡,已是汗流浹背背伴。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峰髓,地道東北人傻寂。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像携兵,于是被迫代替她去往敵國(guó)和親疾掰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 1徐紧、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,980評(píng)論 3 119
  • 背景 最近要做一個(gè)需求静檬,需要把其中兩個(gè)頁面做成全屏的(無導(dǎo)航欄)炭懊。我把這個(gè)主要的代碼抽出來上傳到github上,導(dǎo)...
    半邪亦正閱讀 16,118評(píng)論 19 54
  • 天山深處練兵忙拂檩,戰(zhàn)地黃花分外香侮腹。 指點(diǎn)江山風(fēng)云起,青春熱血保邊疆稻励。
    瀚正閱讀 238評(píng)論 0 4
  • 我的工作就是互聯(lián)網(wǎng)面向全世界華人取名改名望抽,這個(gè)事業(yè)特別的有意義至非,不管相隔千里萬里,也可以有緣相識(shí)糠聪! 你知道嗎荒椭? 一...
    聶老師起名改名閱讀 779評(píng)論 0 1
  • 今天天氣很好,陽光明媚舰蟆,早早起床趣惠,出門辦事,路上也是暢通無阻身害,來到辦事處味悄,還沒有上班,在門口等塌鸯,抓緊等候的時(shí)間侍瑟,看...
    飄飄灑灑一生閱讀 179評(píng)論 0 0