谈一谈拦截导航控制器返回事件(上)——OPP

原创 2017年06月19日 10:43:37

iOS中,UINavigationController 是一个很好用的导航栏控制器,它可以很方便的控制controller 的显示,弹出。操作原理是一个栈,先进后出。
导航栏点击返回时, 会把刚压入栈的controller 弹出,这些已经封装好,不用我们做什么。但有时我们会有一个场景:比如我们填写一个表单时,用户点击了返回按钮,我们这时应该弹出提示,确定退出,但用户确定后,才pop 出这个controller。这时就需要我们拦截返回事件,通常做法就是在当前controller自定义返回按钮,这种做法最简单,但缺点也很明显:

1.每个需要拦截的controller都需要自定义按钮,造成代码冗余。
2.自定义的按钮与系统按钮样式有差别。

那我们这里利用OPP的思想,我们自己封装一个CustomizedNavigationController,继承于UINavigationController,扩展它的功能。CustomizedNavigationController 扩展的功能就是当 push 进来一个controller 时,给他们设置统一样式的返回按钮。所以我们在CustomizedNavigationController 重写:

-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated

继承父类行为的同时,也扩展相应的功能,添加自定义的返回按钮,拥有它的点击事件:

-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    [super pushViewController:viewController animated:animated];

    [self setBackBarButtonItem:viewController];        
}

通过上面的方法,我们都所有push 进来的控制器统一的添加了返回按钮,但有的controller 需要拦截,有的controller 不需要拦截,这就需要controller 告诉我们,对于所有push 进来的控制器来说,这是一个统一的行为。所以我们需要一个父类拥有这个行为,那么他的子类也会继承父类这个行为,只不过每个子类的实现不同。

#import "BaseViewController.h"

@interface BaseViewController ()

@end

@implementation BaseViewController

-(BOOL)viewControllerShouldPop{
    return true;   //默认不拦截
}

需要拦截子类的实现:

#import "OPPInterceptViewController.h"

@interface OPPInterceptViewController ()

@end

@implementation OPPInterceptViewController
-(BOOL)viewControllerShouldPop{

   // 这里写 UIAlertController 询问用户  

    return NO;
}

但用户点击返回按钮时,执行 viewControllerShouldPop 方法,返回true,我们pop controller,返回false,不执行任何操作。

 if([viewController  viewControllerShouldPop]){ 
        [self popViewControllerAnimated:YES];
    }

效果如下:

这里写图片描述

面向对象编程中,我们在父类中定义了一个行为,然后他的子类也都拥有了此行为,不用我们每个子类中在定义一遍,不必造成代码冗余。我们也可以在子类中重写父类的方法,实现不同的功能。但缺点也很明显,从上面的例子我们可以看出:

1.我们必须使用自定义的NavigationController,如果我们不使用CustomizedNavigationController,就无法实现给controller设置自定义的返回按钮。
2.我们要想拥有 viewControllerShouldPop 这个行为时,必须要继承于 BaseViewController,如果controller 不继承于BaseViewController,但push 进来时,因找不到viewControllerShouldPop 方法,程序势必会崩溃。

这不我们不愿看到的。其实我们只想在push 这个点去执行一段我们自己的代码片段,难道只能重写父类的方法吗?
还好我们有AOP(面向切面编程),这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程

OK,那下章我们就来讨论一下如何用AOP实现上述功能。

源码:https://github.com/pzhtpf/CustomizedNavigationController

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ios 3D引擎 SceneKit 开发(1) --起始篇

SceneKit 是一个OC 框架
  • pzhtpf
  • pzhtpf
  • 2015-12-15 14:52
  • 5595

ios 3D引擎 SceneKit 开发(8) --SCNShape 的使用

博客写的没有系统性,真是想到那写到那。 前天有小伙伴问: 如何将一个2D的图案转化成具有深度的3D模型其实很简单,用SCNShape 就可以实现了,看到SCNShape,我们就会立刻想到CA...
  • pzhtpf
  • pzhtpf
  • 2016-10-23 15:10
  • 2533

ios 3D引擎 SceneKit 开发(2) --贴图篇

hello ,大家好,我是Roc.Tian,最近一直在研究苹果自家的3D 引擎 SceneKit ,适当写写博客,总结一下,与大家分享一下,也希望跟大家交流,共同进步。今天简单说一下 SceneKi...
  • pzhtpf
  • pzhtpf
  • 2015-12-26 21:50
  • 9043

ARKit从入门到精通(9)-ARKit让飞机跟着镜头飞起来

转载请注明出处:http://www.jianshu.com/p/30d6c700021a 1.1-ARKit物体跟随相机移动流程介绍 1.2-完整代码1.3-代码下载地址 废话不多说,先看效果...

ARKit从入门到精通(7)-ARCamera介绍

转载请注明出处:http://www.jianshu.com/p/dc1ca646c508 ARCamera是一个相机,它是连接虚拟场景与现实场景之间的枢纽。在ARKit中,它是捕捉现实图像的相机...

ARKit从入门到精通(10)-ARKit让飞机绕着你飞起来

转载请注明出处:http://www.jianshu.com/p/5f9aafbf3cf0 1.1-ARKit物体围绕相机旋转流程介绍 1.2-完整代码1.3-代码下载地址 废话不多说,先看效果...

ios 3D引擎 SceneKit 开发(4) --关于旋转的几点问题(1)

旋转模型是经常遇到了,我们之前用CABasicAnimation 可以旋转一个view,其实它也可以旋转一个SCNNode。首先我们要明白一个概念,每个SCNNode 都有自身的三维坐标系,用CABa...
  • pzhtpf
  • pzhtpf
  • 2016-05-06 22:55
  • 5899

ARKit从入门到精通(5)-ARScnView介绍

转载请注明出处:http://www.jianshu.com/p/00309c11b2f1 AR视图,在第一小节笔者介绍过,ARKit支持3D的AR场景和2D的AR场景,ARSCNView是3D的...

ios 3D引擎 SceneKit 开发(7) --基础的碰撞检测

好久没有写博客了,变懒了,最近工作不多,那就继续坚持写博客。 今天我们来说说SceneKit框架的 Basic Collision Detection,基础碰撞检测。2D中的碰撞检查大家都能能理解,...
  • pzhtpf
  • pzhtpf
  • 2016-10-21 16:13
  • 2615

ios 3D引擎 SceneKit 开发(6) --SCNAction

前面关于旋转的两篇我们利用CABasicAnimation来实现旋转动画,其实在SceneKit中,有一种更为简单的方法去实现一些基础动画,那就是SCNAction,它的执行对象是SCNNode。一个...
  • pzhtpf
  • pzhtpf
  • 2016-05-09 14:53
  • 3125
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)