导航控制器的侧滑返回与全屏滑动返回功能


侧滑返回做法1:

前提条件:采用系统默认的返回按钮
弊端:必须从屏幕左侧的边缘滑动才会实现侧滑返回功能 [LS](https://pan.baidu.com/s/1skV1WOP 密码 zr7w)

  • 代码:
// 直接调用系统的push方法,无需我们写pop时的代码
[self.navigationController pushViewController:vc1 animated:NO];
  • 演示:


    导航控制器的侧滑返回与全屏滑动返回功能_第1张图片
    101.131.gif

侧滑返回做法2:

前提条件:自定义导航栏返回按钮
弊端:必须从屏幕左侧的边缘滑动才会实现侧滑返回功能

  • 代码:自定义导航栏返回按钮
#import "ZBNavController.h"
@interface ZBNavController ()
@property (nonatomic ,strong) id PopVCDelegate;
@end

@implementation ZBNavController
#warning 程序初始运行先执行pushViewController,方法执行完毕,才真真正正激情根控制器添加到屏幕上。然后加到屏幕时候,立刻调用navigationController,整个过程一气呵成.
- (void)viewDidLoad {
    [super viewDidLoad];
    // 导航控制器成为自己的代理。【必不可少,已验证】
    // 既然任何类的对象都能成为导航控制器的代理,那么自己成为导航控制器的代理,有何不可呢?再者:成为代理,必须得遵守协议,设置代理对象是谁,实现代理方法,这三大核心步骤缺一不可。
    self.delegate = self;
}
// 将要push到某个控制器的时候调用。参数viewController表示要push的控制器
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
    if (self.childViewControllers.count != 0) {
         NSLog(@"非根控制器");
    //加载图片
    UIImage *image = [[UIImage imageNamed:@"NavBack"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            // 自定义导航栏的返回按钮
            viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:0 target:self action:@selector(back)];
    }
    //只要重写了pushViewController方法,里面一定要有这行代码,否则就不能实现控制器之间的跳转(入栈和出栈)
    [super pushViewController:viewController animated:animated];
}
- (void)back {
    // 返回上一级
    [self popViewControllerAnimated:YES];
}

// 代理方法:导航控制器的View显示完毕时调用。 参数viewController要显示的控制器
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
    //判断当前显示的控制器是否为根控制器.
    if(self.childViewControllers.count == 1) {
        //是根控制器,设回手势代理。否则侧滑没反应,所以也就无法pop到上一级控制器。[已验证]
        self.interactivePopGestureRecognizer.delegate = self.PopVCDelegate;
    }
}
@end
导航控制器的侧滑返回与全屏滑动返回功能_第2张图片
101.132.gif


全屏滑动返回


#import "ZBNavController.h"

@interface ZBNavController ()
@end

@implementation ZBNavController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 滑动的手势
    // 只要我们触发滑动的手势(滑动屏幕),系统就会调用self.interactivePopGestureRecognizer.delegate的handleNavigationTransition:方法,实现全屏返回功能。
    // 系统底层帮我们实现了handleNavigationTransition:方法,我们只需要调用即可。
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
    // 让当前控制器成为滑动手势的代理
    pan.delegate = self;
    [self.view addGestureRecognizer:pan];//给窗口的根控制器的view添加手势
}

//代理方法。判断是否开始响应手势,返回类型为BOOL.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {// C
    //当前控制器是否为根控制器
        if(self.childViewControllers.count == 1) {// 根控制器
            return NO;// 拖动屏幕没有反应,即不会发生返回
        }else {// 非根控制器
            return YES;// 拖动屏幕有反应,即会发生返回
        }
}
@end

导航控制器的侧滑返回与全屏滑动返回功能_第3张图片
101.130.gif

拓展:自定义导航栏背景颜色,导航栏字体颜色,字体大小

  • 代码:
#import "ZBNavController.h"
@interface ZBNavController ()
@end

@implementation ZBNavController

- (void)viewDidLoad {
    [super viewDidLoad];
}
// 某个类或者子类重写了系统的initialize方法,只有在用这个类创建出对象的情况下,才会调用initialize方法,可能调用过多次
+ (void)initialize {

    if (self == [ZBNavController class]) {
        //获取整个应用程序下所有的导航条.
        //UINavigationBar *bar = [UINavigationBar appearance];
        
        //获取指定类下面的导航条
        UINavigationBar *bar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[ZBNavController class]]];
        
        //导航条的背景图片
        [bar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
   
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        // 导航栏的字体颜色
        //根据可变字典中的key(即NSForegroundColorAttributeName),取出value,即使右边的[UIColor whiteColor]
        dict[NSForegroundColorAttributeName] = [UIColor whiteColor];
        // 导航栏的字体大小
        dict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:20];
        [bar setTitleTextAttributes:dict];
    }
    
    
}
@end
  • 演示:


    导航控制器的侧滑返回与全屏滑动返回功能_第4张图片
    101.132.gif

遇到的bug

  • 出现的问题1:pop控制器的时候,有竖直的黑影
导航控制器的侧滑返回与全屏滑动返回功能_第5张图片
101.128.gif
  • 解决办法:给黑影所在的控制器设置背景颜色。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor orangeColor];
}

导航控制器的侧滑返回与全屏滑动返回功能_第6张图片
101.129.gif

参考部分链接


独立的导航控制器NavigationBar之间切换效果

实现的效果:pop时二级界面的导航栏不会消失隐藏.[LS](https://pan.baidu.com/s/1gfOBbUz 密码 8tma)

系统默认切换效果(共用一个导航条)

导航控制器的侧滑返回与全屏滑动返回功能_第7张图片
101.140.gif

自定义切换效果(两个独立的导航条)

导航控制器的侧滑返回与全屏滑动返回功能_第8张图片
101.134.gif


显示/隐藏navigationBar

  • 在要push的控制器的viewWillAppear方法中设置navigationBar的隐藏或者显示
// 在viewWillAppear实现显示/隐藏navigationBar
-(void)viewWillAppear:(BOOL)animated{
self.navigationController.navigationBar.hidden = YES;
}
导航控制器的侧滑返回与全屏滑动返回功能_第9张图片
101.136.gif

你可能感兴趣的:(导航控制器的侧滑返回与全屏滑动返回功能)