这几天发现在开发的应用不能使用系统的左滑返回手势功能,原因是自定义navigationbar的返回按钮,系统手势就没有用了。通过开启返回手势的方式增加左滑操作。遇到了以下问题,下面是解决方式。下面是转载别人的,出处不详。
从iOS7的Beta版开始,就着手做兼容工作,到Beta4的時候,应用已经基本兼容,只是偶然发现,iOS样式的手势返回,也就是用interactivePopGestureRecognizer返回的时候,出现下面一些列问题。各方调研,无果,史无前例(废话,刚出来的7,上哪有例去--#)。
A,我的应用是自定义的返回按钮图标(默认返回按钮样式不会出现问题3),为了保险,写了这句代码[self.navigationItem setHidesBackButton:YES]。 由于自定义返回按钮,所以iOS7自带返回手势无效。在需要的页面加上navigationController.interactivePopGestureRecognizer.delegate = self 返回手势好用了。
B,于是出现了第二个问题。 在一级视图中,iOS样式返回的手势滑动一下,然后进入二级视图,发现,画面卡住了,按Home键转入后台,再返回应用,发现并没有Crash掉,而是直 接跳到了二级视图里,运行正常了,大家知道push和pop的原理是用进栈出栈完成的,可能因为在一级视图中滑动那一下,影响了视图在栈中的位置。 好,先解决一下这个问题,一级视图中一定要加入self.navigationController.interactivePopGestureRecognizer.enabled = NO;,先把iOS7手势返回屏蔽掉,到二级视图再用self.navigationController.interactivePopGestureRecognizer.enabled = YES打开。就Ok了。
C,好,第三个问题相继出现(其实是跟第二个一起出来的)。 手势返回拖动一半,放手,navigationBar上会出现三个小蓝点,而且位置不规律,可以肯定这个不是项目代码或者图片搞出来的东西,一定是SDK自己蹦出來的。 后台尝试发现UIBarButtonItem的title如果是nil的话,就会有这个问题。 解决方案:把[self.navigationItem setHidesBackButton:YES];去掉,然後把假装成返回按钮的UIBarButtonItem的title设置成@""。
D,大功告成。可见设计要是不按苹果规范来的话,就会遇到各种坑啊。
这片转载的文章解决了我不少问题,下面是自己项目中遇到的问题。
另外也有一些问题:
1返回按钮点击的时候,在继承的方法里做了一些操作,每个控制器不同,同时这个点击事件还完成了返回操作。那么,如果在手势返回时不调用这个方法,就跟点击按钮返回效果不一样,少了一些自定义点击事件。如果调用这个方法,那么就会出现两次返回,手势返回一次,点击事件返回一次。现在的解决方案是在手势的代理
gestureRecognizerShouldBegin中,return NO,也就是手势只负责触发,不负责返回,然后判断需要返回时,调用控制器的返回事件方法,这样,就解决了这个问题。不过这样的缺点显而易见,没有了手势返回的动画,动画不跟手,而是直接返回,跟按一次返回按键一样。优点同样,没有成本,因为完全等同于点击返回按钮,所以没有引入bug。
想过使用手势返回而不用事件方法返回的方案,就是增加一个开关,存在nsuserdefaults中,在手势触发时,关闭开关,再调用返回方法,方法中判断开关,关闭的情况下,不执行跳转的代码,在方法返回时再打开开关恢复原状,这样,返回按钮和返回手势就可以不冲突了。
2对于上文的b步骤,因为我是用的tabbarvc做的根控制器,所以需要处理4个控制器不允许手势返回事件,而且要每个深一层的控制器都要允许控制器手势返回,在项目100多控制器的情况下,一个个添加显然不现实,所以我扩展了viewdidappear方法,在uiviewcontroller的分类中,做了一个扩展方法,这个方法在继承字uiviewcontroller的第一个次基类控制器中的viewdidappear方法中进行了调用,能保证所有控制器都能调用这个方法。在这个分类方法中,我根据根控制的类型,判断是否需要打开手势,如果是这四个控制器,则关闭手势,不是的情况下打开。这样,就能快速解决这个问题了。
目前我的项目中发现的就是以上问题。