1. 程式人生 > >ios全域性返回按鈕和全屏側滑功能

ios全域性返回按鈕和全屏側滑功能

一. 解釋返回控制器

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;
}

3. 這樣就能實現全屏側滑

六. 總結

1. 以上僅僅是一部分方法,還有其它的就交給大家來實現了,有什麼問題,直接給我留言,一起進步,謝謝!!!!