自定义导航栏之滑动返回

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

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

时间: 2024-11-05 03:01:47

自定义导航栏之滑动返回的相关文章

IOS 自定义导航栏标题和返回按钮标题

IOS中自定义导航栏标题: UILabel *titleText = [[UILabel alloc] initWithFrame: CGRectMake(160, 0, 120, 50)]; titleText.backgroundColor = [UIColor clearColor]; titleText.textColor=[UIColor whiteColor]; [titleText setFont:[UIFont systemFontOfSize:17.0]]; [titleTex

自定义导航全屏滑动返回上一页

- (void)viewDidLoad { [super viewDidLoad]; // 获取系统自带滑动手势的target对象 id target = self.interactivePopGestureRecognizer.delegate; // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target ac

实际iOS编程中遇到的自定义导航栏按钮,导致手势返回失效的解决方法

1\在实际编程过程中往往需要自定义导航栏上面的按钮,也就用: - (instancetype)initWithCustomView:(UIView *)customView; 但用了这个方法后可能会导致iOS7,8的手势返回失效,解决方法就是在自定义的导航栏的viewDidLoad方法中添加如下代码 注意:只有用系统的导航栏,或者继承于系统的导航栏才可以用Push方法,并且自带返回手势. - (void)viewDidLoad { [super viewDidLoad]; __weak type

微信小程序自定义导航栏(wx_custom_navigation_bar) 自定义返回键、首页键,动态设置标题,响应式组件

微信小程序自定义导航栏 navigation bar 返回键 首页 github: https://github.com/chen-yt/wx_custom_navigation_bar https://github.com/Superman2113/wx_custom_navigation_bar 代码 navbar组件 navbar.wxml <view class="navbar" style="{{'height: ' + navigationBarHeight

自定义导航栏返回按钮文字

自定义导航栏返回按钮文字 by 伍雪颖 navigationItem.backBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)

ios开发之自定义默认生成的导航栏 标题 颜色 返回按钮

一 修改导航栏颜色    导航栏在哪个页面代码放在那里面 self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:(21.0/255.0) green:(153.0 / 255.0) blue:(224.0 / 255.0) alpha:1];                                                   //定义导航栏颜色 self.navigationItem.t

父子控制器中的自定义导航栏

提到自定义导航栏,大家首先想到的就是自己写个自定义导航控制器,然后设置自己的导航控制器的主题.再把包装着自己控制器的导航控制器的class填上自己写的自定义nav如果遇到个别控制器的导航栏想与众不同,就再写个自定义nav然后再弄个新的导航控制器包裹自己. 可是,如果一个项目中用到了 父子控制器,上面的这种做法就会没有效果.原因就是取不到导航栏. 比如我做的大概架构是一个collectionView的循环引用,让一个个tableview都是包装在我的collectionViewcell里面的,然后

一些关于iOS系统导航栏与自定义导航栏的事情

关于系统导航栏是真的让人又爱又恨,爱的是苹果本身对这个控件的封装已经是很完美了,包括内存.美化.渐变动画等等,一般来说,基本上所有需求都可以满足的.但是你要知道什么东西到了中国,就会发生翻天覆地的变化,例如后台的数据并发.在国内奇葩的产品设计之下,导航栏也是面目全非,反正我看了比较著名的APP,发现他们的导航栏基本都是自定义,其中牵扯最大的问题就是导航栏自身的隐藏.颜色渐变. 其实通过APP运行时,你可以看到系统NavigationBar的分层.一个navigationBar是分很多层的,并非我

React Native自定义导航栏

之前我们学习了可触摸组件和页面导航的使用的使用: 从零学React Native之09可触摸组件 - 从零学React Native之03页面导航 - 经过之前的学习, 我们可以完成一个自定义导航栏了, 效果如下: 我们需要创建一个 NaviBar.js 用来显示顶部的导航栏, 还需要四个界面(Page1.js,Page2.js,Page3.js,Page4.js). 当然还需要修改index.android.js或者index.ios.js 用来处理4个界面的切换. 导航栏NaviBar 实现