iOS 自定義導(dǎo)航--參照系統(tǒng)導(dǎo)航

不以圖片開(kāi)頭的文章都不是好文章

與世無(wú)爭(zhēng).JPG

任何時(shí)候咕村,都不要迷失自己场钉。有一雙清澈的眼睛,可以沉默懈涛,但不要迷離方向逛万;有一顆干凈的心靈,可以容納批钠,但不能承載太多宇植;有一個(gè)優(yōu)雅的姿態(tài),可以美麗埋心,但不要沉溺世事指郁。其實(shí),一切源于自然拷呆,源于清凈闲坎,源于靈魂的修行疫粥。

現(xiàn)狀描述:

一般項(xiàng)目中大概都是一個(gè)tabbar管理幾個(gè)帶導(dǎo)航的控制器,可其中有幾個(gè)控制器沒(méi)有導(dǎo)航腰懂。這時(shí)候就需要進(jìn)入該控制器的時(shí)候隱藏導(dǎo)航梗逮,離開(kāi)的時(shí)候顯示導(dǎo)航。

大概流程就是設(shè)置代理 self.navigationController.delegate = self;
遵守協(xié)議 UINavigationControllerDelegate

#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

并在viewWillAppear中隱藏

[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];

viewWillDisappear中顯示導(dǎo)航绣溜,設(shè)置回導(dǎo)航慷彤,例如:

UIImage *image= [self createImageWithColor:kMainColor];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
//其中:createImageWithColor:是根據(jù)傳遞主題顏色生成圖片
/*
- (UIImage *)createImageWithColor:(UIColor*)color {
    CGRect rect = CGRectMake(0, 0, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context =  UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image =  UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}*/
發(fā)現(xiàn)Bug:

以上這種寫法,一般也不會(huì)有啥問(wèn)題怖喻。除非遇到跳轉(zhuǎn)的界面也是隱藏導(dǎo)航的瞬欧,這時(shí)候有概率出現(xiàn)該顯示導(dǎo)航的卻消失了(復(fù)現(xiàn)過(guò)程:滑動(dòng)來(lái)回調(diào)用viewWillAppearviewWillDisappear

腦袋瓜子嗡嗡的.jpg

構(gòu)思解決方案:

所以干脆讓導(dǎo)航一直都是隱藏狀態(tài),顯示的時(shí)候添加自定義的導(dǎo)航View罢防,當(dāng)然功能都參照著系統(tǒng)的功能

實(shí)施大致過(guò)程關(guān)鍵Code:
  • 初始化 懶加載控件
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initView];
    }
    return self;
}

- (void)initView {
    self.backgroundColor = [UIColor redColor];///kMainColor;
    //根據(jù)公開(kāi)傳遞的參數(shù)按需增加
    //默認(rèn)加載灰色的線
    [self bottomGrayLine];
    [self backBtn];
}
  • 返回按鈕
/// 返回按鈕 默認(rèn)添加 參照l(shuí)eftBarButtonItem
- (JYDisableHightlightBtn *)backBtn {
    if (!_backBtn) {
        _backBtn = [JYDisableHightlightBtn buttonWithType:(UIButtonTypeCustom)];
        [self addSubview:_backBtn];
        //Masonry約束
        [_backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(15);
            make.width.equalTo(80);
            make.height.equalTo(44);
            make.bottom.equalTo(0);
            
        }];
        _backBtn.backgroundColor = [UIColor blueColor];
        [_backBtn setImage:[UIImage imageNamed:@"common_back"] forState:(UIControlStateNormal)];
        //按鈕圖片居左
        _backBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
        //點(diǎn)擊響應(yīng)RAC傳遞信號(hào)
        [[_backBtn rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(__kindof UIControl * _Nullable x) {
            if (self.leftBtnClickedBlock) { //使用block自定義返回或返回根視圖
                self.leftBtnClickedBlock();
            }else {
                [self.viewController.navigationController popViewControllerAnimated:YES];
            }
        }];
    }
    return _backBtn;
}
  • 中間的標(biāo)題
//中間的標(biāo)題
- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc]init];
        [self addSubview:_titleLabel];
        [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.equalTo(self.mas_centerX);
            make.bottom.equalTo(-10);
        }];
        _titleLabel.backgroundColor = [UIColor blueColor];
        _titleLabel.font = [UIFont systemFontOfSize:18];
        _titleLabel.textColor = [UIColor whiteColor];
    }
    return _titleLabel;
}
  • 在頭文件中公開(kāi)屬性艘虎,方便設(shè)置導(dǎo)航按鈕等,如:
//背景
@property (nonatomic, copy) NSString *jy_naviImageName; //titleView
@property (nonatomic, assign) BOOL jy_hideBottomGrayLine;
//左邊
@property (nonatomic, copy) void (^leftBtnClickedBlock)(void); //left
@property (nonatomic, assign) BOOL jy_hiddenBackBtn;

@property (nonatomic, copy) void (^leftBtnsClickedBlock)(UIButton *leftBtns); //lefts需要

//中間
@property (nonatomic, copy) NSString *titleString;
@property (nonatomic, copy) NSString *titleImageString;
  • 當(dāng)然還要仿照系統(tǒng)UINavigationItem還有titleView咒吐、rightBarButtonItem野建、rightBarButtonItems以及是否隱藏返回按鈕,右側(cè)是否可點(diǎn)擊等等

  • 最后在基類中隱藏導(dǎo)航并添加自定義導(dǎo)航視圖恬叹,后續(xù)創(chuàng)建的控制器需要繼承自該基類
/*
 設(shè)置父類的導(dǎo)航代理候生,隱藏導(dǎo)航,并添加自定義導(dǎo)航
 */
#import "JYBaseViewController.h"

@interface JYBaseViewController ()<UINavigationControllerDelegate>

@end

@implementation JYBaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.delegate = self;
    self.baseNaviView = [[JYNaviView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, k_Height_NavBar)];
    [self.view addSubview:self.baseNaviView];
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

#pragma mark - dealloc
- (void)dealloc{
    NSLog(@"%@--dealloc", [self className]);
}
整合到項(xiàng)目中實(shí)際遇到的問(wèn)題:
  1. UISearchControllersearchBar點(diǎn)擊的時(shí)候會(huì)跑到頂部
    解決辦法:個(gè)人建議直接使用UISearchBar設(shè)置樣式后調(diào)用原來(lái)的邏輯绽昼。
  2. 同一個(gè)界面直接顯示和配合WMPageController使用唯鸭。
    解決辦法:在其中任意一個(gè)推出界面時(shí)增加type屬性(或成員變量),根據(jù)屬性來(lái)判斷是否隱藏導(dǎo)航視圖硅确。如:
初始化賦值type目溉,枚舉最好,此處簡(jiǎn)寫
- (instancetype)initWithWMPage:(NSInteger)type {
    if (self = [super init]) {
        _type = type;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if (self.type == 1) {
        self.baseNaviView.hidden = YES;
    }else {
        self.baseNaviView.titleString = @"微視頻";
        self.baseNaviView.hidden = NO;
    }
    //...

    CGFloat startY = self.baseNaviView.hidden ? 0 : CGRectGetMaxY(self.baseNaviView.frame);
    CGFloat videoH = self.baseNaviView.hidden ? ScreenHeight - self.tabBarController.tabBar.height- k_Height_NavBar - 41 : ScreenHeight- k_Height_NavBar- k_Height_Bottom;
    self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, startY, ScreenWidth, videoH) style:(UITableViewStylePlain)]; //只有導(dǎo)航?jīng)]有tabbar菱农,劉海屏系列減34缭付,非減0
}
  1. 有的界面不顯示自定義的導(dǎo)航視圖
    解決辦法:查看視圖層級(jí),如果被遮擋那就帶到最前方[self.view bringSubviewToFront:self.baseNaviView];

  2. 子視圖被遮擋
    解決辦法:如果是代碼創(chuàng)建的視圖循未,那么創(chuàng)建的時(shí)候CGRectMake的Y參數(shù)使用CGRectGetMaxY(self.baseNaviView.frame)或者k_Height_navBar陷猫,高度看情況是否需要再減掉。如果是Xib拖的控件的妖,那么建議top約束到superView而不是Safe Area绣檬,然后在控制器中self.safeToTop.constant = k_Height_NavBar;

  3. 執(zhí)行Block會(huì)警告:Capturing 'self' strongly in this block is likely to lead to a retain cycle
    解決辦法:建議導(dǎo)入RAC框架或YYCategories,創(chuàng)建弱引用self

    @weakify(self)
    self.baseNaviView.leftBtnClickedBlock = ^{
        @strongify(self)
        [self.navigationController popToRootViewControllerAnimated:YES];
    };

...

  • BTW:Demo
    煩惱都忘掉.JPG
?著作權(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)離奇詭異搁凸,居然都是意外死亡媚值,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門护糖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)褥芒,“玉大人,你說(shuō)我怎么就攤上這事嫡良∶谭觯” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寝受,是天一觀的道長(zhǎng)坷牛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)很澄,這世上最難降的妖魔是什么京闰? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮甩苛,結(jié)果婚禮上蹂楣,老公的妹妹穿的比我還像新娘。我一直安慰自己讯蒲,他們只是感情好痊土,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著墨林,像睡著了一般赁酝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旭等,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天赞哗,我揣著相機(jī)與錄音,去河邊找鬼辆雾。 笑死肪笋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的度迂。 我是一名探鬼主播藤乙,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惭墓!你這毒婦竟也來(lái)了坛梁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤腊凶,失蹤者是張志新(化名)和其女友劉穎划咐,沒(méi)想到半個(gè)月后拴念,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馅巷。 院中可真熱鬧膛虫,春花似錦、人聲如沸钓猬。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)敞曹。三九已至账月,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澳迫,已是汗流浹背局齿。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(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)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,100評(píng)論 1 32
  • 翻譯自“View Controller Programming Guide for iOS”卒稳。 1 定義子類 使用...
    lakerszhy閱讀 2,394評(píng)論 0 5
  • 概述 摘要:從制作一個(gè)看圖app和了解關(guān)鍵概念開(kāi)始swift編程蹋半。 概念:Constants and variab...
    lbhw閱讀 466評(píng)論 0 1
  • navigation技巧 [A].獲取 導(dǎo)航欄所有的視圖控制器 獲取 導(dǎo)航欄所有的視圖控制器,選擇想要跳轉(zhuǎn)的那個(gè)視...
    goyohol閱讀 526評(píng)論 1 0
  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多充坑,會(huì)對(duì)里面所有的內(nèi)容的引用計(jì)數(shù)+1减江,想要解決就用__block...
    炙冰閱讀 2,486評(píng)論 1 14