ios全域性返回按鈕和全屏側滑功能
阿新 • • 發佈:2019-02-11
一. 解釋返回控制器
1. 導航條返回控制器按鈕:當一個控制器進入另外一個控制器的時候,需要從另外一個控制器中返回,如果程式猿不自定義返回按鈕,那麼控制器中的導航條會預設返回按鈕在導航條的左側.
2. 功能圖
二. 全域性返回按鈕—–方法一
1. 思路:重寫push方法.重寫系統的push方法,就能實現全域性返回按鈕的功能.
1.1 push方法程式碼:
//重寫系統的push方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
//如果當前的控制器數不等於0,那麼說明有子控制器,此時才需要返回按鈕
if (self.childViewControllers.count != 0) {
NSLog(@"非根控制器");
//設定返回按鈕
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageWithOriImageName:@"NavBack"] style:0 target:self action:@selector(back)];
}
//如果控制器的數量等於0,那麼久保持系統原有的做法
[super pushViewController:viewController animated:animated];
}
1.2 push方法中跳轉控制器的方法實現:
//監聽跳轉控制器方法的實現
- (void)back {
//返回上一個控制器
[self popViewControllerAnimated:YES];
}
1.3 注意:如果就這樣直接將圖片設定到導航條上,圖片會渲染,那麼就達不到想要的效果.那麼我給大家提供一個分類,大家只要使用這個分類中的方法就可以實現對圖片的保護不被渲染.(直接在設定圖片的時候就直接呼叫這個方法)
+ (UIImage *)imageWithOriImageName:(NSString *)imageName {
//傳入一張圖片,返回一張不被渲染的圖片
UIImage *image = [UIImage imageNamed:imageName];
return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
三. 全域性返回按鈕—–方法二
1. 方法二思路:由於我們知道,系統本身就自帶了返回控制器的按鈕,只是系統的按鈕會配有文字說明,我們要求的返回按鈕是沒有返回按鈕的描述.所以我們可以想辦法讓描述的文字離開螢幕,然後再將顏色修改為自己想要的顏色,就能達到效果.
1.1 拿到全域性導航條中的item
//拿到全域性的導航條中的item--->這種方法比較霸道
UIBarButtonItem *item = [UIBarButtonItem appearance];
1.2 設定返回按鈕的顏色為自己需求的顏色
//設定圖片顏色
NSMutableDictionary *dict2 = [NSMutableDictionary dictionary];
dict2[NSForegroundColorAttributeName] = [UIColor whiteColor];
[item setTitleTextAttributes:dict2 forState:UIControlStateNormal];
1.3 設定返回按鈕的描述文字尺寸—-離開螢幕的尺寸
//將返回按鈕的描述文字尺寸設定為離開螢幕的尺寸
[item setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -64) forBarMetrics:UIBarMetricsDefault];
1.4 這種方法同樣能達到效果(比較容易實現)
四. 方法一帶來的後遺症及解決方法
1. 當重寫了系統的push方法時,系統的側滑功能就會失效.
2. 側滑功能實現原理:當用戶使用側滑功能的時候,系統是通過代理去通知實現側滑功能,但是如果重寫了push,那麼代理知道,既然重寫了push方法,那麼代理就會通知系統不要去實現側滑功能,這樣就使得側滑功能失效,或者產生bug.
3. 思路:我們就通過對代理的控制,來實現對側滑功能的控制
3.1 設定一個屬性,用來儲存在push方法重寫之前的代理
//設定一個屬性儲存系統的代理
@property (nonatomic, strong) id popDelegate;
//將系統的代理儲存(在view載入完畢就賦值--->viewDidLoad)
self.popDelegate = self.interactivePopGestureRecognizer.delegate;
3.2 在重寫的push方法中,讓代理等於空—-意思是不讓代理去通知系統側滑功能失效
self.interactivePopGestureRecognizer.delegate = nil;
3.3 在代理方法中,將原來儲存的代理屬性,賦值給系統,讓系統代理保持原來的工作
#pragma mark - 實現代理方法
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//判斷控制器是否為根控制器
if (self.childViewControllers.count == 1) {
//將儲存的代理賦值回去,讓系統保持原來的側滑功能
self.interactivePopGestureRecognizer.delegate = self.popDelegate;
}
}
4. 這樣就完整的解決了重寫push方法後,側滑功能失效的問題
五. 全域性側滑功能
1. 概念:所謂全域性側滑功能,指的是在非根控制器中,只要滑動螢幕的某一部分就能達到返回控制器的效果.”四”中的側滑功能僅僅侷限於使用者從螢幕的最側邊才能滑動,意思是當用戶想從螢幕的中間滑動切換控制器的時候,是不管用的.
2. 實現思路: 新增手勢
2.1 新增滑動手勢
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
2.2 方法handleNavigationTransition:怎麼出現?
//通過直接列印就能得出此引數
NSLog(@"%@",self.interactivePopGestureRecognizer);
2.3 設定手勢的代理為控制器
//設定手勢的代理為當前控制器,讓控制器去執行
pan.delegate = self;
2.4 實現代理方法
#pragma mark - 實現手勢代理方法
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//如果控制器的數量不為1
return self.childViewControllers.count != 1;
}