项目中用到系统右滑返回时解决取消滑动的方法

2018-06-26  本文已影响0人  Neal_f
   //禁用系统手势,因为跟splitView手势有冲突
      self.interactivePopGestureRecognizer?.isEnabled = false
//        let target = self.interactivePopGestureRecognizer?.delegate
//        let pan:UIPanGestureRecognizer = UIPanGestureRecognizer(target: target!, action: Selector(("handleNavigationTransition:")))

      pan = UIPanGestureRecognizer(target: self, action: #selector(handleNavigationTransition(_ :)))
      self.view.addGestureRecognizer(pan)
      pan.delegate = self

本来想交换一下系统的handleNavigationTransition,增加状态判断,发现不好做,原因是handleNavigationTransition并不是类的成员方法,获取不到啊,它是target的方法不好获取,放弃了。
其次有想用 NSInvoke 方法调用handleNavigationTransition 发现swift不好用,就用了oc
就是target用自己的方法,在自己的手势方法里调用系统的handleNavigationTransition,这样又能使用系统的右滑,又能获取手势的状态了。
现在可以获得它的状态了,发现并不是想象的那样,没有理解cancle状态:取消手势后才触发。。。。悲剧了
看来还是要判断手势的位移了

//MARK: 处理右滑返回取消/失败的问题
    @objc func handleNavigationTransition(_ sender: UIPanGestureRecognizer) {

        let target = self.interactivePopGestureRecognizer?.delegate
        let selector = Selector(("handleNavigationTransition:"))
        DealHandle.invoke(target, selector: selector, arguments: [sender])
        print("swizzle state: ---- \(sender.state.rawValue)")

        //处理右滑返回到首页时取消了滑动,侧边栏仍然显示的错误
        if sender.state == UIGestureRecognizerState.ended && self.viewControllers.count == 1{
            let position = sender.location(in: sender.view)
            if position.x > 0 && position.x < UIScreen.width/2   {
                self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.primaryHidden
            }
        }
    }

最后贴一下DealHandle.invoke的方法,也就是最简单的调用

//此方法用来调用系统的方法
+ (void) invoke:(id)target selector:(SEL)selector arguments:(NSArray *)arguments {

    //生成selector的函数签名
    //若有另一个selector1与这个selector返回值、参数列表相同,也可以用selector1的函数签名
    NSMethodSignature *signature = [[target class] instanceMethodSignatureForSelector:selector];
    //根据函数签名生成一个NSInvocation对象,NSInvocation对象的生成仅能通过其类方法实现
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

    //设置target、selector,并且target、selector分别占据其参数列表第0个和第1个的位置
    [invocation setTarget:target];
    [invocation setSelector:selector];

    id num = arguments[0];

    [invocation setArgument:&num atIndex:2];
    //转发此消息
    [invocation invoke];
}
上一篇下一篇

猜你喜欢

热点阅读