美文网首页优化
一句话笔记(24)(连续 Push)

一句话笔记(24)(连续 Push)

作者: 天空中的球 | 来源:发表于2017-05-09 11:58 被阅读122次

    一句话笔记,某段时间内遇到或看到的某个可记录的点。 2017-05-09

    • 1、如何确定是 Tab 切换的页面 还是 Pop 回来的页面
    • 2、解决在某些情况下出现连续 Push 的情况的 BUG

    一、如何确定是 Tab 切换的页面 还是 Pop 回来的页面

    • 思路一: 从 UITabBarControllerDelegate 处判断
    - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UINavigationController *)viewController {
        if ([viewController.topViewController isKindOfClass:TestViewController.class]) {
            TestViewController *testVC = (TestViewController *)viewController.topViewController;
            testVC.isTabBarSwitch = YES;
        }
        return YES;
    }
    
    • 思路二: 从 重写 UINavigationController Pop 判断
    - (UIViewController *)popViewControllerAnimated:(BOOL)animated {
        self.isPop = YES;
        return [super popViewControllerAnimated:animated];
    }
    

    然后想了下,还是选择了思路二,毕竟这样假如后期其他 ViewController 也有用到其的时候,方便扩展。

    二、解决在某些情况下出现连续 Push 的情况的 BUG

    有时候,我们在网络条件比较差的情况下,容易出现那种连续 Push 的情况,让人很烦。

    • 解决方案一:在其代理中通过一个 临时变量 判断
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if (self.isSwitching) {
            return;
        }
        self.isSwitching = YES;
        [super pushViewController:viewController animated:animated];
    }
    
    //- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    //    self.isSwitching = YES;
    //}
    
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        self.isSwitching = NO;
    }
    

    注意下面那个方法是代理呈现出来的。

    • 解决方案二: 通过判断当前 ViewController 来解决
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
        // 判断上一个控制器和现在的控制器是不是同一个
        if ([self.topViewController isMemberOfClass:[viewController class]]) {
            return;
        }
        [super pushViewController:viewController animated:animated];
    }
    
    

    通常情况下,解决 网络比较差的情况下出现的连续 Push, 个人认为采取方案二解决。

    PS: 防止触摸事件触发新方法的一个系统方法。

    
    //开始禁止交互  
    - (void)beginIgnoringInteractionEvents; 
    //结束禁止交互  
    - (void)endIgnoringInteractionEvents;  
    //是否禁止了交互  
    - (BOOL)isIgnoringInteractionEvents;    
    

    所以此处在某些 Target-Action 处也可以直接,防止在这个过程中的第二次交互:

    - (IBAction)testAction:(id)sender {
        [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
        // Do Some
        FirstViewController * firstVC = [[FirstViewController alloc] init];
        [self.navigationController pushViewController:firstVC animated:YES];
        
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    }
    

    但是实际上这样是不能很好的解决的 连续Push 的过程,它只是保证在每一次 Action 的时候外部禁止交互, 而网络环境比较弱的时候,这个过程都还没开始,却被执行了多遍 Action, 从而其实上并没有解决这个问题。所以,此处有待商榷。

    所以,目前个人暂时比较认同方案二的, 简单直接。

    • 当然如果项目中出现一个类真需连续调用的情况,那就另当别论。别说,还真有这种情况。
    • 而采用方案一也有一个问题,当其是 RootViewController 的时候, 那个 方法会走两次,所以也无效。
    • (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    
    于是最终,我是为了解决 网络条件差的情况下,偶尔出现的连续 Push ,所以我采用两者合一。
    
    • (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
      // 对于同一个 ViewController 防止连续 Push
      if ([self.topViewController isMemberOfClass:[viewController class]]) {
      if (self.isSwitching) {
      return;
      }
      self.isSwitching = YES;
      }
      [super pushViewController:viewController animated:animated];
      }

    • (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
      self.isSwitching = NO;
      }

    
    备注参考: 
    http://blog.lessfun.com/blog/2015/09/09/uiviewcontroller-push-pop-trap/

    相关文章

      网友评论

      • 简书lu:- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if (self.isSwitching) {
        return;
        }
        self.isSwitching = YES;
        [super pushViewController:viewController animated:animated];
        }

        - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        self.isSwitching = NO;
        }
        这两个方法都是代理体现出来的吗?

        - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        self.isSwitching = NO;
        }
        这个方法什么时候调用啊

        天空中的球:最前者不是代理,直接是 NavgationController 的 push 调用方法
        后者是代理方法,当你有 Push 跳转成功后就调用啊
        这个直接看 其 Api 就知道了
      • 简书lu:你写的tips都是实战中遇到的问题,我很想了解,但是有些问题我没遇到,就不能理解,比如这篇文章的第一点,麻烦你解答一下这个问题出现的情境😜
        天空中的球:这种情景比较特殊吧,可以这样了解下,实际上这点就是对 UITabBarController 和 UINavagtionController 的代理理解。具体中在我们 TabBarController 某个 SubController 显示的时候,它要确认上一次从哪个地方返回的时候,这种需求比较少吧,了解下就好了。

      本文标题:一句话笔记(24)(连续 Push)

      本文链接:https://www.haomeiwen.com/subject/nwbmtxtx.html