UINavgation日常小bug-有兴趣的朋友可以看看

UINavgation日常

UINavgation

  • 今天在做一个小Demo,发现一个Bug,挺有意思的,就是在你不断调用Navigation- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;方法的时候,发现在不断点击一个按钮来调用这个方法,在点击返回调用- (UIViewController *)popViewControllerAnimated:(BOOL)animated;这个方法,这是在快速多次点击返回不但没有返回,还多次向Navigition里面添加控制器。

  • 额,黑苹果录制有点缺陷,自行脑补画面吧。
  • 这是什么问题呢,代码不多,可以看看,那么问题究竟出在哪里呢?
//push
//触发点击事件
[btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];

//接收按钮点击处理
- (void)btnClick:(UIButton *)btn{
    [self.navigationController pushViewController:[[ETRecommendController alloc] init] animated:YES];
}

//pop
//触发点击时间
[backBtn addTarget:self action:@selector(pop)
//接受点击事件
- (void)pop{
    [self popViewControllerAnimated:YES];
}
 
  • 看看现在的分析

    • 我想点击push就调用push方法,返回就调用pop,并且只调用一次。
    • 现在点击push的确是显示一次,点击pop的时候,明显的看到添加了好多子控制器进去,而实际上也的确添加了好多自控器(实际的确如此)
    • 这里我是自定义Navigation的,那么可能是我自定义里面的代码里面写逻辑不对,与系统的冲突,于是换了系统的Navigation,然而结果一样。
    • 不得不说一个细节是在按钮的两端点才回出现这个bug,在中间点则一切正常。
  • 于是乎我发现在接受按钮push点击事件的方法调用多次,但是明明看到我还没返回根控制器啊,同时也看到我点击的返回按钮啊,突然间我发现我是这样调用push方法的[self.navigationController pushViewController:[[ETRecommendController alloc] init] animated:YES];注意后面的animated:YESNavigation的跳转带动画效果,而这个动画效果是通过CoreAnimation的专场动画来实现的,而动画的需要时间,而在RunLoop里面的NSDispalyLink与NStimer那么如果在一定时间内没有执行完任务会自动跳过,而现在会不会类似这样呢,毕竟是都是基于线程运行的,而线程的架构模式又是RunLoop,亦即是说执行动画需要时间,在这个时间里面没有执行完动画,那么RunLoop直接处理下一个Source
  • 额...,如果是这样的话,那么直接把动画设为NO就行了吧,于是把YES换成NO,的确,一点问题也没有,问题这样似乎是解决了,请留意我上面说的一个细节。
  • 在按钮的两端点才回出现这个bug,在中间点则一切正常

  • 如果说在两端和中间点击的效果一样的话,这样动画的YES和NO就很有说服力了,但是现在明显不是。
  • 于是乎现在又是这样一个状况
    • 在我们点击过去的时候,push键(非返回键)动画效果的时候,变成了这样一个局势:中间的一个模块不能接收相应,而周围可以,也就是说,中间和周围不是同一块控件,毕竟根据响应者链条,寻找最合适的View,所以,如果能接收事件那他一定是同一块View,除非他不遵循响应者链条,而现在就是这个局势,一个控件居然不遵循响应者链条,好吧,这个猜想有点大胆,理由也比较勉强。
    • 这里需要普及一下苹果的一些细节的知识,在我们点击iPhone键盘的时候,例如我点击了g,那么苹果会从他系统自带的猜词字典里面猜想我们下一个会按什么,这是可能是good,也可能是god,但是可以肯定的是o的触控范围一定比某一些字母的触控范围大,也就是说虽然我们看起来键盘一直没有变化,他的每个字母能接收事件的范围永远都在动态变化的,这也是苹果用户体验比较好的一个细节。
    • 行了,有了上面的小提示,你应该想到我接下来要讲什么了吧,就是我们的返回按钮的接收事件的范围会被放大,当然这只是我的一个猜想,那么如果我的猜想成功的话,现在就是这个局势,中间一个push键的确push后不能点击,但是他的响应范围被放大了,所以就形成了中间点击正常,边框点击会调用push方法,这样猜想貌似合理,这种猜想与上面的那种猜想结合起来应该会比较合理,但是毕竟是猜想。
  • 至于解决方案,很简单,我猜你也想到了,不过为什么会出现这个bug,这才是最重要的,至少求学态度没有错,解决方案:大体是:
    • 如果是自定义Navigation的话,可以在重写的push方法里面检查navigation里面是否已经存在了这个控制器。
    - (BOOL)checkIsExit:(id)VC{
    for (id classObj in self.childViewControllers) {
        Class class = [classObj class];
        if ([VC isKindOfClass:class]) {
            return YES;
        }
    }
    return NO;
}
 
    • 如果是系统自带的话,可以在navigation的childrenControllers的count的变化的时候判断是否取出最后一个,这里可能会用到KVO,需要提醒的是,系统的KVO并不是对一切属性都可用的,如果是使用Swift的话推荐一个第三方框架Observable-Swift,这个框架很好的利用了Swift的泛型,如果的OC,自行到github上寻找框架。
时间: 2024-10-01 07:29:12

UINavgation日常小bug-有兴趣的朋友可以看看的相关文章

记录日常小bug

①处刚开始写的时候忘记加这一行,然后效果一直出不来,发现的时候真笑死 ②处错将boolean写成Boolean 原文地址:https://www.cnblogs.com/js-ctrl-u/p/object-simple.html

观CSDN网站小Bug有感

今天早上在浏览博客的时候偶然发现CSDN博客的数据出现了异常,我也是头一次看到这么明显的Bug,具体什么表现呢?先来看两个截图,如下:    经常看CSDN博客的人一眼就可以看出来哪里出了问题,那就是博文的阅读次数停止了更新,换句话说就是那个数据失效了,我推断数据异常大概出现在昨天中午的时候,到现在为止没有解决掉,其实这也没什么,只是看着有点别扭而已,世界上没有不存在完美的程序,我也是头一次看到大型网站出现小bug,也许是以前见过但是没有看出来或者意识到. 当然我对异常的原因和解决办法更感兴趣,

【ASP.net控件】DropDownList数据绑定一个小bug

绑定数据出现这种情况,明明在第一项插入了一条数据,却始终在DropDownList中没有显示出来. 代码如下: if (!IsPostBack) { //绑定城市 DataTable dtCity = new HighSearch().GetCitySelect(); DropDownList1.DataSource = dtCity; DropDownList1.DataValueField = "citycode"; DropDownList1.DataTextField = &q

ShardedJedisPool 中可用连接数的小bug

ShardedJedisPool中,returnBrokenResource() 及 returnResource() ,为施放资源.关闭连接的方法,若重复调用,导致 _numActive 当前活动数一直递减,会出现负数的情况. 假如在一个方法中设置了三个jedis连接,在获取第一或第二个连接时出现异常,在抛出异常或者finally中总是施放这三个资源,会导致池中的连接连续施放三次,从而变成负数. 这样会出现连接池最大连接数配置无效的情况. 以下片段代码: public class RedisU

vue示例之transition-另外发现一个vue(可能的)小bug

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="//cdn.bootcss.com/animate.css/3.5.2/animate.css" rel="stylesheet"> <style&

R语言学习中的小bug:R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数

遇到了小bug: R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数 看到网上别人的做法,发现了用class(A)和class(B)之后才发现,是因为读入的时候数据的类型不对,A.B的类型并不是matrix,才导致了这个问题. 用as.matrix来变型一下,就OK了. R语言学习中的小bug:R中矩阵相乘错误于A %*% B: 需要数值/复数矩阵/矢量参数,布布扣,bubuko.com

Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决

原文:Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决 最近一直在开发XX的uwp版本,也是边摸索边做,最近遇到几个比较奇怪的问题,记录于此. 1.项目可用部署到PC,但无法部署到手机,提示以下错误: 错误 : DEP0001 : 意外错误: Install failed. Please contact your software vendor. (Exception from HRESULT: 0x80073CF9 为了方便开发,我将常用的类库引用好.默认的几个页面做

iOS开发之使用UICollectionView实现美团App的分类功能【偶现大众点评App的一个小bug】

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下载:http://dwz.cn/RwTjl 游戏视频预览:http://dwz.cn/RzHHd 游戏开发博客:http://dwz.cn/RzJzI 游戏源代码传送:http://dwz.cn/Nret1 例如以下图示[美团和大众点评]: 实现分类控件功能的思路: 1.实现collection v

js动画--一个小bug处理下

对于上面的课程我们很好的处理了一个小bug,那么我们现在讲程序进行优化一下,前一节的程序中,我们处理处理的属性都是写死了的.为了我们能够很好的对某个属性进行操作的话.我们这样来设置. js文件 window.onload=function(){ var ls=document.getElementsByTagName("li"); for(var i=0,l=ls.length;i<l;i++){ ls[i].timer=null; ls[i].onmouseover=funct