美文网首页
吐个小槽

吐个小槽

作者: seej | 来源:发表于2018-06-22 13:39 被阅读0次

    郑重声明:本文只是对编写代码过程中不合理的操作进行吐槽,同时希望能够将自己平时调试bug的思路进行分享,不附带对代码作者以及任何程序猿(媛)的人身攻击,请不要上纲上线。希望大家在阅读完这篇文章后能够以平常心对待从天而降的bug。(这其实是一篇技术博😏)

    至于文中bug的始作俑(勇)者,我依然认为她是一个不可多得的合作伙伴。(谁还没写过几个惊天大bug)

    开始之前,请大家打开网易云,搜索凉凉,带上耳机,扶好坐稳...

    近期公司项目新增了一个大模块,然而在测试的时候偶然发现老早以前的模块某个xib文件约束报红,出于职业操守我计划顺便将这个模块进行测试,结果粗大事儿咧,模块中有一个界面的toolbar在我的疯狂点击下竟然纹丝不动。(手机钢化膜都戳破了,应该不是我力道不够的问题)

    excuse me?这个toolbar有点冷,难道是我不够帅?不存在的,我让我们后台大帅比点了,也不行。😏(请不要留言要联系方式,人孩子都叫我叔叔了。)

    稳重的toolbar

    根据我多年的经验,如果这个toolbar一直是这样它不可能上线。(严肃脸)

    想到这里我决定先给自己泡一杯菊花茶,可惜没有枸杞有点小遗憾。

    作为一名合格的程序员,还是要勇于背锅的,也许是我某一天一不小心动了某行代码导致这里出问题了。
    嗯,有道理,先回退版本build一下。
    然而事实证明并没有什么卵用。那还等什么,甩锅啊!!!

    望着手里的 iphoneXXX plus,我不经陷入了沉思.
    它究竟经历了什么?
    那是一个天气晴朗,万里无云,天空中飘着蒙蒙细雨的深夜,那一天我再次收到了系统版本升级通知,依稀记得那天没有枸杞,也没有菊花茶,有点微微发抖的手错误的按下了立即更新...
    二十分钟后,望着系统焕然一新的手机,我又一次陷入了沉思... 唉,还是把Xcode也升级了吧。

    哦!我知道了,一定是系统版本的原因,不是bug。找了旧版本的测试机build,看着活蹦乱跳的toolbar我的内心是崩溃的。

    代码如下:

    self.toobar = [[CSSMyCustomDetailToobar alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
    [self.toobar toobarWithItems:itemArray[0]];
    

    问题可能出在 CSSMyCustomDetailToobar :

    @interface CSSMyCustomDetailToobar : UIToolbar
    @property (nonatomic,assign) id <CSSMyCustomDetailToobarDelegate > delegateToobar;
    - (void)toobarWithItems:(NSArray *)items;
    @end
    

    再看toobarWithItems方法:

    - (void)toobarWithItems:(NSArray *)items 
    {
        [items enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((self.bounds.size.width/items.count)*idx, 0, self.bounds.size.width/items.count, self.bounds.size.height)];
            btn.tag = idx+10;
            if ([CSSUserInfoManager manager].isHiddenSwing) {
                btn.tag = btn.tag + 1;
            }
            [btn addTarget:self action:@selector(operationAction:) forControlEvents:UIControlEventTouchUpInside];
            UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:obj[@"image"]]];
            imageView.centerX  = btn.width/2;
            imageView.y = btn.frame.origin.y+5;
    
            UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, [imageView getFrame_Bottom], btn.width, btn.height- [imageView getFrame_Bottom])];
            titleLabel.text = obj[@"title"];
            
            
            [btn addSubview:imageView];
            [btn addSubview:titleLabel];
            titleLabel.font = [UIFont systemFontOfSize:12];
            titleLabel.textColor = [UIColor see_colorWithHex:0x666666];
            titleLabel.textAlignment = NSTextAlignmentCenter;
          
            [self addSubview:btn]; //?????? why?
            
        }];
        self.backgroundColor = [UIColor whiteColor];
    }
    

    以上代码 除了 //?????? why? ,其他的都是原汁原味。

    让我们来解析一下这段代码,借此琢磨一下作者当时的心路历程。

    解析中
    .
    ..
    ...
    ....
    .....
    ......
    .......
    ........
    .........
    ..........
    ...........
    ............
    解析失败!!!
    是否强制解析,此操作可能会造成无法挽回的后果。 (y / n)
    y
    😒

    从上面的代码来看,这里应该是想要把button添加在toolbar上面,这个是没毛病的。
    but...
    wait, wait, wait,等一下...
    [self addSubview:btn]; ???
    视图层次结构走起来。

    iOS11.4系统下toolbar层次结构

    怪不得点不动,按钮上面盖四层视图是什么鬼?
    切回旧版本系统看一下

    iOS10.0系统下toolbar层次结构

    纵观不同系统下层次结构,不难发现两个系统版本下调用UIToolbar的addSubview:方法视图添加的位置是不同的。
    iOS10.0下按钮被添加在_UIVisualEffectFilterView上层,处于所有子视图之上,zIndex最大。
    iOS11下UIToolbar多了_UIToolbarContentView和_UIButtonBarStackView两层视图并且这两层视图是在_UIVisualEffectSubview之上的,而我们的按钮就被添加在_UIVisualEffectSubview上层,因此我们添加的按钮就被_UIToolbarContentView和_UIButtonBarStackView覆盖了接收不到点击事件。

    嗯,终于找到了原因看来能够早点下班回家了。
    重新修改代码,使用按钮创建UIBarButtonItem并添加进toolbar,千万别问我UIBarButtonItem怎么添加到toolbar。

    迫不及待的build一下,fuck,竟然还是不能点。
    感觉我的智商受到了惨无人道的侮辱。
    再看看视图层次结构:

    iOS11.4下视图层次结构

    竟然少了两层,不错不错,还是取得了一点点成就的。
    我们发现,修改之前按钮上面 _UIToolbarContentView和_UIButtonBarStackView 各有两层,现在只剩一层了,少的那一层去哪里了呢?
    我们在图中找找线索:

    iOS11.4下视图层次结构

    由此猜测,可能这一坨视图是由两个toolbar合成的。(为我自己的机智点个赞👍)
    其中一个toolbar被另一个toolbar使用addSubview方法添加进自己的视图。
    通过不懈的努力,在控制器中发现了以下代码:

    [self.navigationController.toolbar addSubview:self.toobar];
    self.navigationController.toolbarHidden = NO;
    

    @¥#%@……#%……@#&*¥#……
    咳咳... 不好意思,语速太快岔气了。
    进过一番苦战,toolbar终于正常工作,你以为就能下班了?
    too young too naive!

    不知各位之前有没有注意到下面这几行代码:

     UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((self.bounds.size.width/items.count)*idx, 0, self.bounds.size.width/items.count, self.bounds.size.height)];
     UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:obj[@"image"]]];
     imageView.centerX  = btn.width/2;
     imageView.y = btn.frame.origin.y+5;
     UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, [imageView getFrame_Bottom], btn.width, btn.height- [imageView getFrame_Bottom])];
     titleLabel.text = obj[@"title"];
     [btn addSubview:imageView];
     [btn addSubview:titleLabel];
     titleLabel.font = [UIFont systemFontOfSize:12];
     titleLabel.textColor = [UIColor see_colorWithHex:0x666666];
     titleLabel.textAlignment = NSTextAlignmentCenter;
    

    说到这几行代码那可就牛逼了,又是加减又是乘除的,一看就是出自文化人之手。

    虽然这几行代码运行出来的结果是没问题的,但是怎么就看着这么奇怪呢,这里是通过给button添加了一个UIImageView和一个UILabel然后进行了一系列运算计算frame来实现文字和图片的折行显示(图文混排),但是这种方法看起来好像有那么一点点不优雅。

    其实这里可以采用属性字符串来达到同样的效果,代码如下:

    + (instancetype)see_attributedStringWithImage:(UIImage *)image imageSize:(CGSize)size title:(NSString *)title titleColor:(UIColor *)color fontSize:(CGFloat)fontSize lineSpace:(CGFloat)space {
        //创建文本附件
        NSTextAttachment * atta = [[NSTextAttachment alloc]init];
        //设置图片
        atta.image = image;
        //设置图片大小
        atta.bounds = CGRectMake(0, 0, size.width, size.height);
        NSAttributedString * att = [NSAttributedString attributedStringWithAttachment:atta];
        //追加空行
        NSMutableAttributedString * attM = [[NSMutableAttributedString alloc]initWithAttributedString:att];
        NSAttributedString * str = [[NSAttributedString alloc]initWithString:@"\n " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:space]}];
        [attM appendAttributedString:str];
        //追加文字
        NSAttributedString * titles = [[NSAttributedString alloc]initWithString:[NSString stringWithFormat:@"\n%@",title] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize],NSForegroundColorAttributeName:color}];
        [attM appendAttributedString:titles];
        return attM.copy;
    }
    

    这样可以省去很多不必要的数学运算。

    至此本期吐槽结束。

    至于这段代码出自何人之手并不重要,(谁还没有年轻过,毕竟大家都是从菜鸡一步步过来的。)重要的是目前线上App在iOS11.4版本的设备上是瘫痪的... 我的内心受到了极大的伤害(疼痛到无法夫吸),不说了改胤禩(八阿哥)去。

    (以下情节纯属虚构,如有雷同纯属巧合,请随意入座。)
    一年前:
    NSLog(@"h");
    NSLog(@"e");
    NSLog(@"l");
    NSLog(@"l");
    NSLog(@"o");
    NSLog(@" ");
    NSLog(@"w");
    NSLog(@"o");
    NSLog(@"r");
    NSLog(@"l");
    NSLog(@"d");
    

    唉呀妈呀,终于写完了。

    嗯,不错,我这段代码老牛逼了。后面来的人看到了我这段代码一定会对我顶礼膜拜。
    要不然署个名留个联系方式?
    算了算了,做人要低调,低调,低调!

    一年后:

    嗯? 这里好像有一个bug。

    嗯... 这个bug值得好好研究一下。

    咦?这里为什么要这样写呢?

    妈的,这sb代码谁写的。@#¥¥&¥#(@#()@😒

    相关文章

      网友评论

          本文标题:吐个小槽

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