修改导航条返回按钮的思考

注意:当前控制器是:UINavigationController,是tabBar下所有控制器下统一创建的Navigation控制器

问题一:

  • 设置leftBarButtonItem和rightBarButtonItem后,会覆盖系统的返回按钮,失去了滑动返回的手势功能。

解决方案:

//记录系统的代理属性
self.popDelegate = self.interactivePopGestureRecognizer.delegate;
//滑动返回功能
        self.interactivePopGestureRecognizer.delegate = nil;

self.interactivePopGestureRecognizer是系统的滑动手势(可以打印出一些想要的信息)
  • 还需要在以下代理方法(完全展示完调用)中恢复系统代理,系统的方法不能随意改变,不然会有新的bug
#pragma mark - 导航控制器的代理方法
// 完全展示完后调用
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // 如果展示的控制器是根控制器,就还原pop手势代理
    if (viewController == [self.viewControllers firstObject]) {

        self.interactivePopGestureRecognizer.delegate = self.popDelegate;

    }
}

新需求:

  • 系统的滑动手势只有在旁边才有效,需要在更大范围有效果

打印系统的手势:

NSLog(@"%@",self.interactivePopGestureRecognizer);


<UIScreenEdgePanGestureRecognizer: 0x7f9c22148dd0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7f9c2213db80>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7f9c22148850>)>>

系统滑动手势类型:UIScreenEdgePanGestureRecognizer
target:_UINavigationInteractiveTransition
action:handleNavigationTransition:

查看过程

  • 取出系统的手势对象
UIScreenEdgePanGestureRecognizer *ges = self.interactivePopGestureRecognizer;
    NSLog(@"%ld",ges.edges);
  • 打印唯一的edges属性 == 2
  • 查看系统的 UIRectEdge edges 结构体所包含的值;
typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone  = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft  = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);
  • 可以看到结果和UIRectEdgeLeft相匹配,已经固定死

解决方案:自定义手势

  • 防止和系统的手势发生冲突
      self.interactivePopGestureRecognizer.enabled = NO;

以下代码所干的事:

取出系统手势的target对象, 然后再取出某个对象里面的属性
  • 1.KVC 前提条件:必须知道属性名
  • 2.利用运行时机制

    • 导入框架 #import
  UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
  或者
  UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];

  [self.view addGestureRecognizer:pan];

新bug:和直接设置self.interactivePopGestureRecognizer.delegate = nil;所出现的bug一样,在根控制器右滑后,无法再点击left/right按钮

解决方案:

取消根控制器触发bug的右边滑动的手势

  • 遵守UIGestureRecognizerDelegate协议
  • 设置代理pan.delegate = self;
  • 实现代理方法
 #pragma mark - 手势代理方法
// 是否开始触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // 判断下当前控制器是否是根控制器

    return (self.topViewController != [self.viewControllers firstObject]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值