吐個小槽

鄭重聲明:本文只是對編寫代碼過程中不合理的操作進(jìn)行吐槽,同時希望能夠?qū)⒆约浩綍r調(diào)試bug的思路進(jìn)行分享,不附帶對代碼作者以及任何程序猿(媛)的人身攻擊,請不要上綱上線。希望大家在閱讀完這篇文章后能夠以平常心對待從天而降的bug。(這其實(shí)是一篇技術(shù)博??)

至于文中bug的始作俑(勇)者,我依然認(rèn)為她是一個不可多得的合作伙伴。(誰還沒寫過幾個驚天大bug)

開始之前,請大家打開網(wǎng)易云,搜索涼涼,帶上耳機(jī),扶好坐穩(wěn)...

近期公司項(xiàng)目新增了一個大模塊,然而在測試的時候偶然發(fā)現(xiàn)老早以前的模塊某個xib文件約束報紅,出于職業(yè)操守我計劃順便將這個模塊進(jìn)行測試,結(jié)果粗大事兒咧,模塊中有一個界面的toolbar在我的瘋狂點(diǎn)擊下竟然紋絲不動。(手機(jī)鋼化膜都戳破了,應(yīng)該不是我力道不夠的問題)

excuse me?這個toolbar有點(diǎn)冷,難道是我不夠帥?不存在的,我讓我們后臺大帥比點(diǎn)了,也不行。??(請不要留言要聯(lián)系方式,人孩子都叫我叔叔了。)

穩(wěn)重的toolbar

根據(jù)我多年的經(jīng)驗(yàn),如果這個toolbar一直是這樣它不可能上線。(嚴(yán)肅臉)

想到這里我決定先給自己泡一杯菊花茶,可惜沒有枸杞有點(diǎn)小遺憾。

作為一名合格的程序員,還是要勇于背鍋的,也許是我某一天一不小心動了某行代碼導(dǎo)致這里出問題了。
嗯,有道理,先回退版本build一下。
然而事實(shí)證明并沒有什么卵用。那還等什么,甩鍋?。。?!

望著手里的 iphoneXXX plus,我不經(jīng)陷入了沉思.
它究竟經(jīng)歷了什么?
那是一個天氣晴朗,萬里無云,天空中飄著蒙蒙細(xì)雨的深夜,那一天我再次收到了系統(tǒng)版本升級通知,依稀記得那天沒有枸杞,也沒有菊花茶,有點(diǎn)微微發(fā)抖的手錯誤的按下了立即更新...
二十分鐘后,望著系統(tǒng)煥然一新的手機(jī),我又一次陷入了沉思... 唉,還是把Xcode也升級了吧。

哦!我知道了,一定是系統(tǒng)版本的原因,不是bug。找了舊版本的測試機(jī)build,看著活蹦亂跳的toolbar我的內(nèi)心是崩潰的。

代碼如下:

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? ,其他的都是原汁原味。

讓我們來解析一下這段代碼,借此琢磨一下作者當(dāng)時的心路歷程。

解析中
.
..
...
....
.....
......
.......
........
.........
..........
...........
............
解析失?。。?!
是否強(qiáng)制解析,此操作可能會造成無法挽回的后果。 (y / n)
y
??

從上面的代碼來看,這里應(yīng)該是想要把button添加在toolbar上面,這個是沒毛病的。
but...
wait, wait, wait,等一下...
[self addSubview:btn]; ???
視圖層次結(jié)構(gòu)走起來。

iOS11.4系統(tǒng)下toolbar層次結(jié)構(gòu)

怪不得點(diǎn)不動,按鈕上面蓋四層視圖是什么鬼?
切回舊版本系統(tǒng)看一下

iOS10.0系統(tǒng)下toolbar層次結(jié)構(gòu)

縱觀不同系統(tǒng)下層次結(jié)構(gòu),不難發(fā)現(xiàn)兩個系統(tǒng)版本下調(diào)用UIToolbar的addSubview:方法視圖添加的位置是不同的。
iOS10.0下按鈕被添加在_UIVisualEffectFilterView上層,處于所有子視圖之上,zIndex最大。
iOS11下UIToolbar多了_UIToolbarContentView和_UIButtonBarStackView兩層視圖并且這兩層視圖是在_UIVisualEffectSubview之上的,而我們的按鈕就被添加在_UIVisualEffectSubview上層,因此我們添加的按鈕就被_UIToolbarContentView和_UIButtonBarStackView覆蓋了接收不到點(diǎn)擊事件。

嗯,終于找到了原因看來能夠早點(diǎn)下班回家了。
重新修改代碼,使用按鈕創(chuàng)建UIBarButtonItem并添加進(jìn)toolbar,千萬別問我UIBarButtonItem怎么添加到toolbar。

迫不及待的build一下,fuck,竟然還是不能點(diǎn)。
感覺我的智商受到了慘無人道的侮辱。
再看看視圖層次結(jié)構(gòu):

iOS11.4下視圖層次結(jié)構(gòu)

竟然少了兩層,不錯不錯,還是取得了一點(diǎn)點(diǎn)成就的。
我們發(fā)現(xiàn),修改之前按鈕上面 _UIToolbarContentView和_UIButtonBarStackView 各有兩層,現(xiàn)在只剩一層了,少的那一層去哪里了呢?
我們在圖中找找線索:

iOS11.4下視圖層次結(jié)構(gòu)

由此猜測,可能這一坨視圖是由兩個toolbar合成的。(為我自己的機(jī)智點(diǎn)個贊??)
其中一個toolbar被另一個toolbar使用addSubview方法添加進(jìn)自己的視圖。
通過不懈的努力,在控制器中發(fā)現(xiàn)了以下代碼:

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

@¥#%@……#%……@#&*¥#……
咳咳... 不好意思,語速太快岔氣了。
進(jìn)過一番苦戰(zhàn),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;

說到這幾行代碼那可就牛逼了,又是加減又是乘除的,一看就是出自文化人之手。

雖然這幾行代碼運(yùn)行出來的結(jié)果是沒問題的,但是怎么就看著這么奇怪呢,這里是通過給button添加了一個UIImageView和一個UILabel然后進(jìn)行了一系列運(yùn)算計算frame來實(shí)現(xiàn)文字和圖片的折行顯示(圖文混排),但是這種方法看起來好像有那么一點(diǎn)點(diǎn)不優(yōu)雅。

其實(shí)這里可以采用屬性字符串來達(dá)到同樣的效果,代碼如下:

+ (instancetype)see_attributedStringWithImage:(UIImage *)image imageSize:(CGSize)size title:(NSString *)title titleColor:(UIColor *)color fontSize:(CGFloat)fontSize lineSpace:(CGFloat)space {
    //創(chuàng)建文本附件
    NSTextAttachment * atta = [[NSTextAttachment alloc]init];
    //設(shè)置圖片
    atta.image = image;
    //設(shè)置圖片大小
    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;
}

這樣可以省去很多不必要的數(shù)學(xué)運(yùn)算。

至此本期吐槽結(jié)束。

至于這段代碼出自何人之手并不重要,(誰還沒有年輕過,畢竟大家都是從菜雞一步步過來的。)重要的是目前線上App在iOS11.4版本的設(shè)備上是癱瘓的... 我的內(nèi)心受到了極大的傷害(疼痛到無法夫吸),不說了改胤禩(八阿哥)去。

續(xù)

(以下情節(jié)純屬虛構(gòu),如有雷同純屬巧合,請隨意入座。)
一年前:
NSLog(@"h");
NSLog(@"e");
NSLog(@"l");
NSLog(@"l");
NSLog(@"o");
NSLog(@" ");
NSLog(@"w");
NSLog(@"o");
NSLog(@"r");
NSLog(@"l");
NSLog(@"d");

唉呀媽呀,終于寫完了。

嗯,不錯,我這段代碼老牛逼了。后面來的人看到了我這段代碼一定會對我頂禮膜拜。
要不然署個名留個聯(lián)系方式?
算了算了,做人要低調(diào),低調(diào),低調(diào)!

一年后:

嗯? 這里好像有一個bug。

嗯... 這個bug值得好好研究一下。

咦?這里為什么要這樣寫呢?

媽的,這sb代碼誰寫的。@#¥¥&¥#(@#()@??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近在回顧經(jīng)典,連著兩個月都在看武俠小說。在中學(xué)時期,我特別喜歡看古龍。而現(xiàn)在古龍金庸連著看,發(fā)現(xiàn)對金庸小說的喜歡...
    修煉的大海閱讀 254評論 0 1
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,175評論 3 119
  • 最近深深被一種我配不上的思想困擾。靜下來梳理出來,想給自己一點(diǎn)鼓勵。 “我不配”的思想,其實(shí)是一種潛意識,扎根在我...
    卡諾09閱讀 666評論 0 0
  • 1988年的電視劇《八月桂花香》的主題曲,那個時候電視劇好少啊,對這部電視劇記憶尤深,主題曲也是特別好聽。 塵緣 ...
    JessicaH2017閱讀 744評論 6 10
  • 曾一直以為寫作必須行云流水,瀟灑飄逸,一氣呵成,斗酒詩百篇,才發(fā)現(xiàn),那不過是神話故事和謠言。 多數(shù)人寫作往往都會遇...
    六嬸兒閱讀 151評論 2 1

友情鏈接更多精彩內(nèi)容