首页 > 代码库 > 自定义导航栏之滑动返回

自定义导航栏之滑动返回

以前我们所有的滑动返回,只是系统自带的滑动返回,只能在屏幕的左侧滑动才能到达效果。

但是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)

 

自定义导航栏之滑动返回