不以圖片開(kāi)頭的文章都不是好文章
任何時(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)用viewWillAppear
和viewWillDisappear
)
構(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)題:
-
UISearchController
的searchBar
點(diǎn)擊的時(shí)候會(huì)跑到頂部
解決辦法:個(gè)人建議直接使用UISearchBar
設(shè)置樣式后調(diào)用原來(lái)的邏輯绽昼。 - 同一個(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
}
有的界面不顯示自定義的導(dǎo)航視圖
解決辦法:查看視圖層級(jí),如果被遮擋那就帶到最前方[self.view bringSubviewToFront:self.baseNaviView];
子視圖被遮擋
解決辦法:如果是代碼創(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;
執(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