zoukankan      html  css  js  c++  java
  • iOS项目之“返回”手势操作相关

        在程序中,总会设置“返回”按钮,但不可能在每一个控制器中都去设置一次“返回”按钮,那如何设置全局的“返回”按钮呢?

        首先自定义一个导航控制器,在tabBarController中添加子控制器时,使用这个自定义的导航控制器,所以在这个导航控制器中重写push方法设置“返回”按钮就可以了。

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        // 如果是根控制器,则不需要添加“返回”按钮
        if (self.childViewControllers.count > 0) {
            viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem wx_itemBackWithTarget:self action:@selector(backClick)];
            viewController.hidesBottomBarWhenPushed = YES;
        }
        [super pushViewController:viewController animated:animated];
    }

        需要注意的是,如果自己设置了“返回”按钮,那么系统的边缘滑动返回功能就失效了,这是为什么呢?

        边缘滑动返回功能失效的原因:

            1>分析:边缘滑动功能属于手势操作,在UINavigationController中找到手势属性,打印输出看手势是否被清空

    @property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        if (self.childViewControllers.count > 0) {
            viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem wx_itemBackWithTarget:self action:@selector(backClick)];
            viewController.hidesBottomBarWhenPushed = YES;
    
            // 输出手势
            WXLog(@"%@",self.interactivePopGestureRecognizer);
        }
        [super pushViewController:viewController animated:animated];
    }

            输出结果:

    2016-05-20 14:15:39.874 caravan-alter[3652:128235] <UIScreenEdgePanGestureRecognizer: 0x7f80c9e80860; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7f80c9e53d50>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7f80c9ea1ad0>)>>

            结论:手势并没有被清空,所以排除手势被清空的可能。

            2>分析:手势代理做了一些事情,导致手势失效

            在viewDidLoad中输入以下代码:

    self.interactivePopGestureRecognizer.delegate = nil;

            结论:将代理清空时,边缘滑动手势恢复,但出现的问题是,如果在根控制器继续使用边缘滑动手势操作,那么在下一次push的时候会出现程序假死的情况。将代理清空

            解决:将代理设置为self,判断手势是否恢复,只需要判断在根控制器下,不需要滑动手势即可。

    // 两个方法都可以,二选一即可
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        return self.childViewControllers.count > 1;
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        return self.childViewControllers.count > 1;
    }

        为了给用户更好的体验效果,可以给程序添加全屏滑动效果。

        实现:根据打印输出边缘滑动手势,不难发现一些东西:

      UIScreenEdgePanGestureRecognizer:屏幕边缘手势

      target=<_UINavigationInteractiveTransition 0x7f80c9ea1ad0>

      action=handleNavigationTransition:

        有了这些信息,只需要找到_UINavigationInteractiveTransition这个类就可以了,当设置手势代理之前打印输出self.interactivePopGestureRecognizer.delegate,可以发现手势代理就是这个类,实现代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
        // 判断手势什么时候触发
        pan.delegate = self;
        // 添加手势
        [self.view addGestureRecognizer:pan];
        
        // 添加了全屏手势,边缘手势就没什么用了
    //    self.interactivePopGestureRecognizer.delegate = self;
    }

        全屏手势就这样实现了!

  • 相关阅读:
    Codeforces 1237D. Balanced Playlist
    Codeforces 1237C2. Balanced Removals (Harder)
    使用excel计算指数平滑和移动平均
    HP滤波原理浅学
    第二章平稳时间序列模型——ACF和PACF和样本ACF/PACF
    第二章平稳时间序列模型——AR(p),MA(q),ARMA(p,q)模型及其平稳性
    第一章时间序列基础——差分方程和求解(二)
    R中的par()函数的参数
    你真的懂了R中的stem函数是如何绘制茎叶图的么?
    关于R中的mode()和class()的区别
  • 原文地址:https://www.cnblogs.com/sjxjjx/p/5512173.html
Copyright © 2011-2022 走看看