實用小技巧(十五):左側向右滑動返回上一級控制器

版本記錄

版本號 時間
V1.0 2017.07.15

前言

在app中,我們經常有需求就是滑動左側邊距向右,就會回到上一級控制器。感興趣的可以看看我寫的其他小技巧。
1. 實用小技巧(一):UIScrollView中上下左右滾動方向的判斷

2. 實用小技巧(二):屏幕橫豎屏的判斷和相關邏輯
3.實用小技巧(三):點擊手勢屏蔽子視圖的響應
4.實用小技巧(四):動態的增刪標簽視圖
5.實用小技巧(五):通過相冊或者相機更改圖標
6.實用小技巧(六):打印ios里所有字體
7. 實用小技巧(七):UITableViewCell自適應行高的計算
8. 實用小技巧(八):數字余額顯示的分隔
9.實用小技巧(九):類頭條模糊背景的實現
10.實用小技巧(十):晃動手機換后臺服務器網絡
11.實用小技巧(十一):scrollView及其子類顯示的一些異常處理
12.實用小技巧(十二):頭像圖片縮放以及保存到相冊簡單功能的實現
13.實用小技巧(十三):一種類酷我音樂盒動畫實現
14.實用小技巧(十四):生成跳往applestore指定app的方法

功能需求

很多時候我們的app為了獲得很好的交互體驗,那么只要不是跟控制器,就可以向右滑動屏幕,返回上一級控制器。其實自從iOS7以后系統默認自帶了側滑功能,當用戶在界面的左邊滑動的時候,就會有側滑功能,返回上一級控制器。

首先要讓大家看一下代碼組織結構。

代碼結構

下面看一下代碼。

1.AppDelegate.m


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    JJVC1 *vc1 = [[JJVC1 alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc1];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    return YES;
}

2. JJVC1.m
#import "JJVC1.h"
#import "JJVC2.h"

@interface JJVC1 ()

@end

@implementation JJVC1

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"VC1";
    self.view.backgroundColor = [UIColor magentaColor];
    
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidTapped)];
    [self.view addGestureRecognizer:tapGesture];
}

#pragma mark - Action && Notification

- (void)viewDidTapped
{
    JJVC2 *vc2 = [[JJVC2 alloc] init];
    [self.navigationController pushViewController:vc2 animated:YES];
}

@end
3.JJVC2.m
#import "JJVC2.h"
#import "JJVC3.h"

@interface JJVC2 ()

@end

@implementation JJVC2

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"VC2";
    self.view.backgroundColor = [UIColor blueColor];

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidTapped)];
    [self.view addGestureRecognizer:tapGesture];
}

#pragma mark - Action && Notification

- (void)viewDidTapped
{
    JJVC3 *vc3 = [[JJVC3 alloc] init];
    [self.navigationController pushViewController:vc3 animated:YES];
}

@end

4. JJVC3.m
#import "JJVC3.h"

@interface JJVC3 ()

@end

@implementation JJVC3

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"VC3";
    self.view.backgroundColor = [UIColor greenColor];
}

@end

系統此時自帶的側滑效果是管用的,可以返回上一級控制器,具體效果如下所示。

側滑功能展示

手勢失效

有時候我們會發現左滑的手勢失效了,具體失效的原因很多,其中有一種手動的方式可以放左邊側滑的返回上一級控制器失效,我們在vc2和vc3中,加入一句代碼。

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

就會發現左邊側滑功能失效了。手勢可以失效,那我們有時候是別的原因引起的,如果手勢失效我們可以這么解決。

self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;

但是這里還有個問題:這行代碼確實可以實現滑動返回了,但是在根視圖的時候也可以側滑返回,這樣當你再次在根視圖觸發一些 Action 的時候就不執行了。具體解決方法如下。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.navigationController.viewControllers.count > 1) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    }
    else{
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
}

還可以調用系統的其他方法完成這個功能,可以遵循下面的方法嘗試一下。

  • 獲取系統自帶滑動手勢的target對象。
id target = self.navigationController.interactivePopGestureRecognizer.delegate;
  • 創建全屏滑動手勢~調用系統自帶滑動手勢的target的action方法。
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];

  • 設置手勢代理~攔截手勢觸發。
pan.delegate = self;

  • 給導航控制器的view添加全屏滑動手勢。
[self.view addGestureRecognizer:pan];
  • 將系統自帶的滑動手勢禁用。

self.navigationController.interactivePopGestureRecognizer.enabled = NO;
  • 攔截手勢觸發的方法。
//  return NO;則不需要觸發滑動手勢
//  return YES;則需要觸發滑動手勢

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{}

下面我們看一下代碼。

#import "JJVC2.h"
#import "JJVC3.h"

@interface JJVC2 () <UIGestureRecognizerDelegate>

@end

@implementation JJVC2

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"VC2";
    self.view.backgroundColor = [UIColor blueColor];

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidTapped)];
    [self.view addGestureRecognizer:tapGesture];
    
    id target = self.navigationController.interactivePopGestureRecognizer.delegate;
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
    pan.delegate = self;
    [self.view addGestureRecognizer:pan];
    
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    
}

#pragma mark - Action && Notification

- (void)viewDidTapped
{
    JJVC3 *vc3 = [[JJVC3 alloc] init];
    [self.navigationController pushViewController:vc3 animated:YES];
}

#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    //如果有多種手勢的話,可以在這里進行自定義設置,我這里就選擇均有效了。
    
    return YES;
}

@end

具體效果如下所示。

左側滑的自定義實現

這里看見我只在從vc2中加的代碼,所以可以左滑動返回到vc1,但是沒有在vc3中加入這段代碼,vc3中系統的返回還被我禁掉了,所以只能點擊導航左側返回按鈕返回了。

后記

這些小功能,都很簡單,玩玩還挺有意思~~~

鎂鋁
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容