ios push的时候出现页面失去响应的问题解决参考

一、问题描述

 使用iPhone 真机测试过程中,当从ViewController A push到ViewController B时程序失去响应,按主屏按钮将程序切换到后台,再返回前台,程序恢复正常,且显示ViewController B。该问题不是确定出现,但是出现的比较频繁。

 

二、问题分析及解决方案

1. 问题分析

经网上查找类似问题解决方案和对代码的分析发现,此问题的发生与3个方面有比较大的关系:

1.)push动画是否开启,只有当开启动画时,问题才有一定几率发生

2. )当前ViewController 是否是Root ViewController

3. )是否支持interactivePopGestureRecognizer(既右滑pop)

仔细分析如下:

      在当前ViewController是Root ViewController时,由于已经是NavigationController栈中的最后一个ViewController是不应该执行pop操作的,但由于interactivePopGestureRecognizer是对整个栈中所有的ViewController开启的,因此如果不做处理,默认Root ViewController也支持interactivePopGestureRecognizer,当Root ViewController interactivePopGestureRecognizer手势时会试图去pop Root ViewController,一旦这种识别发生了,再通过点击等方式push ViewController(带动画)时,程序就会卡死在被Push ViewController的viewWillAppear方法执行之后。  

      这种情况只有在push操作开启动画时才会发生,至于为什么,不太清楚。可能之前Root ViewController 识别interactivePopGestureRecognizer后,试图启动pop动画但是失败,当再启动push动画时就会出问题。

2. 解决方法

 

方法一:

 1)取消push动画

一般不太建议此方法,因为动画没了影响用户体验;

2) 在Root ViewController上使interactivePopGestureRecognizer手势失效

我采用的是如下方法: 

第一步:在Root ViewController的viewDidLoad中设置

self.navigationController.interactivePopGestureRecognizer.delegate = self;         

第二步:添加如下代理方法,使interactivePopGestureRecognizer手势失效

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

    if ([self.navigationControllerrespondsToSelector:@selector(interactivePopGestureRecognizer)]

        && gestureRecognizer ==self.navigationController.interactivePopGestureRecognizer

        && self.navigationController.visibleViewController == [self.navigationController.viewControllers objectAtIndex:0]) {

        NSLog(@"Gesture blocked===手势锁定");
        return NO;
    }
    NSLog(@"Gesture begin===手势开启");
    return YES;
}

方法二:

在RootViewController的viewDidAppear方法中设置

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

在RootViewController viewDidDisappear方法或被push的ViewController的viewDidAppear方法中设置

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

但是这种方法处理可能会对其他页面的手势有影响可能存在问题。因为有的时候会出现viewDidAppear不执行就可能会出bug,实测出现过不执行的情况。

 

其他方法:

网上有一种继承UINavigationController类并重写push和pop方法,在其中设置interactivePopGestureRecognizer.enabled属性,但我实测发现直接会使App挂起,此处不多做介绍了

 

三、其他发现

1. 测试发现:ViewController的viewDidAppear方法不一定会执行,有时候会从viewWillAppear方法直接跳到viewWillDisappear方法,可能是场景切换太快造成的。

2. 测试发现:UINavigationControllerDelegate的didShowViewController方法不一定执行,不执行的原因不详。

 

四、其他

手势中的设定优先顺序,避免冲突处理

[A requireGestureRecognizerToFail:B]函数,它可以指定当A手势发生时,即便A已经滿足条件了,也不会立刻触发会等到指定的手势B确定失败之后才触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值