郑重声明:本文只是对编写代码过程中不合理的操作进行吐槽,同时希望能够将自己平时调试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]; ???
视图层次结构走起来。
怪不得点不动,按钮上面盖四层视图是什么鬼?
切回旧版本系统看一下
纵观不同系统下层次结构,不难发现两个系统版本下调用UIToolbar的addSubview:方法视图添加的位置是不同的。
iOS10.0下按钮被添加在_UIVisualEffectFilterView上层,处于所有子视图之上,zIndex最大。
iOS11下UIToolbar多了_UIToolbarContentView和_UIButtonBarStackView两层视图并且这两层视图是在_UIVisualEffectSubview之上的,而我们的按钮就被添加在_UIVisualEffectSubview上层,因此我们添加的按钮就被_UIToolbarContentView和_UIButtonBarStackView覆盖了接收不到点击事件。
嗯,终于找到了原因看来能够早点下班回家了。
重新修改代码,使用按钮创建UIBarButtonItem并添加进toolbar,千万别问我UIBarButtonItem怎么添加到toolbar。
迫不及待的build一下,fuck,竟然还是不能点。
感觉我的智商受到了惨无人道的侮辱。
再看看视图层次结构:
竟然少了两层,不错不错,还是取得了一点点成就的。
我们发现,修改之前按钮上面 _UIToolbarContentView和_UIButtonBarStackView 各有两层,现在只剩一层了,少的那一层去哪里了呢?
我们在图中找找线索:
由此猜测,可能这一坨视图是由两个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代码谁写的。@#¥¥&¥#(@#()@😒
网友评论