以前我们所有的滑动返回,只是系统自带的滑动返回,只能在屏幕的左侧滑动才能到达效果。
但是QQ,新浪微博之类的应用,有在屏幕中间滑动也能返回的效果。
下面我们来看具体的实现代码:
我需要创建一个类继承 UINavigationController
OC语言实现:
#import "BaseNavigationController.h" @interface BaseNavigationController () @end @implementation BaseNavigationController - (void)viewDidLoad { [super viewDidLoad]; //*** 主要代码 NSArray *array = [self.interactivePopGestureRecognizer valueForKey:@"_targets"]; id target = [[array firstObject] valueForKey:@"target"]; SEL sel = @selector(handleNavigationTransition:); UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] init]; [self.interactivePopGestureRecognizer.view addGestureRecognizer:panGesture]; [panGesture addTarget:target action:sel]; //*** self.navigationBar.barTintColor = [UIColor colorWithHex:ThemeColor]; self.navigationBar.tintColor = [UIColor whiteColor]; self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; self.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self; } - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } @end
Swift 3.0语言实现:
import UIKit class CustomNavigationController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() //获取系统的 Pop 手势 guard let systemGesture = interactivePopGestureRecognizer else {return} //获取手势添加到 View 中 guard let gestureView = systemGesture.view else {return} let targets = systemGesture.value(forKey: "_targets") as? [NSObject] guard let targetObjc = targets?.first else {return} //取出 target guard let target = targetObjc.value(forKey: "target") else {return} //取出 action let action = Selector(("handleNavigationTransition:")) //创建自己的 Pan 手势 let panGesture = UIPanGestureRecognizer() gestureView.addGestureRecognizer(panGesture) panGesture.addTarget(target, action: action) } override func pushViewController(_ viewController: UIViewController, animated: Bool) { //隐藏要 push 的控制器的 tabbar viewController.hidesBottomBarWhenPushed = true super.pushViewController(viewController, animated: animated) } }
其中,"_targets" 是使用 runtime 运行时来获取的
OC语言实现:
//使用运行时获取所有属性的名称 unsigned int count = 0; Ivar *ivars = class_copyIvarList(UIGestureRecognizer.class, &count); for (unsigned int i = 0; i < count; i++) { NSString *name = [NSString stringWithUTF8String:ivar_getName(ivars[i])]; NSLog(@"name == %@",name); }
Swift 3.0语言实现:
//使用运行时获取所有属性名称 var count:UInt32 = 0 let ivars = class_copyIvarList(UIGestureRecognizer.self, &count)! for i in 0..<count { let ivar = ivars[Int(i)] let name = ivar_getName(ivar) print(String(cString: name!)) }
注意:当然使用 class_copyIvarList 了需要 free(ivars)