# DiDi（十四）

> 原文：https://pjhubs.com/2018/03/19/DiDi%EF%BC%88%E5%8D%81%E5%9B%9B%EF%BC%89/
>
> 作者：PJHubs · 发布于 2018-03-19 · 标签：iOS、DiDi

## 2018-03-19

好了，今天欢送同组的iOS实习生撤了，不知道为啥心里有种轻松解脱感？？？尴尬。

简单分析了一下，自定义了一个升级弹窗。首先是为了满足产想要让文本左对齐的需求，其次是为了能够和整体App的UI风格进行统一，我也想学习一波编写一波通用性UI类库。最核心的地方就是要保证能够在Window上显示出来，所以做法就是非常粗暴的直接通过shareApplication拿到keyWindow即可，然后在Appdelegate中的didFinishLaunching...和applicationWillEnterForeground方法中调用版本检查，po出这个自定义的升级弹窗即可。

初步简单的研究了一个内部库`ONEUIKit/ONEProgressHUD`的实现，等我再花一些时间研究透彻了再来给大家分享一波（这个库就是滴滴出行App中的HUD！！！），其中又发现了一个好玩的API——`UIAccessibilityPostNotification`，使用起来就只需要post一个通知，然后跟上文本信息，居然就能够在当用户开启了VoiceOver后进行读屏操作，真是有趣！当初还以为VoiceOver也要打一个target去做呢。先欠大家一篇正式解说！

大半个下午的时间都在重构之前同事因为他没听清产品需求，从而导致了Android同学之前天天“日了狗”，正确的需求是：当用户进入到通用浏览器后，允许开启横竖屏，当用户点击左上角的回退时，关闭所有页面的横竖屏开关，并且当用户是横屏退出时，把它给强制转换成竖屏。

对，你没看错，我又重新写了一遍所有逻辑，把之前花了巨大力气才做好的所有页面横竖屏代码统统删掉，因为在中午的时候我突然意识到，如果这一次不这么做了，以后的任何一个新需求，要出新页面，都会被逼去写一大坨恶心的横竖屏代码！！！不要再问我为什么要写这么横竖屏适配代码了！因为从未使用过SB/xib，我内心已经非常草泥马了。所以今天下定决心，一定要把正确的需求给改回来。（第一次把花了巨大力气写好的代码全都删了，感觉自己的孩子夭折了。

记录一个遗忘点：@property里的readOnly属性实际上不是不可改，可以通过KVC的方式去修改，通过使用字符串标识属性间接访问对象属性，从而绕过setter/getter，给我感觉readOnly特别就想是给开发者提供一个警示或者说一种约束（我觉得协议可能比较好），只是不推荐这么做，并不是不让你改，hhhh。

重载和重写：简单来说重载是同样方法名，但参数不同；重写是方法名和参数名都是相同的。（要不然我老是恍惚。）

## 2018-03-20

😔，又送走了一位和我共事了快半年的Android同事，从蜗牛到滴滴，真的很难得，虽然当初也有吐槽过他做游戏的思路，但是慢慢的想起来，他是真的不喜欢做游戏。😂。而且他是我大学以来能够遇到为之不多的能够一同真正干事的人，我只是觉得水的人太多了（当然，我自己也很水），但是水归水嘛，总得认识到自己的不足啊，可是有些人就是打肿脸充胖子，明明自己已经水得不行了，还得充大头，搞得很难一同共事下去。同样，我们也祝愿Android小哥能够去到更大平台，以后说不定以后咱们还得抱人家大腿赏口饭吃是不？

中午下去吃散伙饭的时候，突然！有位其它部门的同事在钉钉找到了我，说了句hello后丢了两个GitHub地址给我！！！当时我在跟大家伙打坦克大战呢！打完后立马切回钉钉，一看，好吧，我最担心的事情发生了。跟其它同学说滴滴的安全部门是多么多么的严，leader也跟我们说不能上传公司内部代码到GitHub上！我也一直铭记着，但是就是没想到我居然在之前的一篇博客中之前为了省事把工程中的podspec内容全部粘上去了，出现了红线关键字，当时差点没把我吓屎，以为会被全员通告。给自己提个醒提个醒。。。

今天刷完了`ONEProgressHUD`这个库，使用起来跟`MBProgressHUD`非常相似，经过两天吭吭哧哧的过了一遍代码，基本上知道了实现细节，算是完成了第一份元源码的阅读，不过产品不让我用这个库，说是后续有自定义HUD需求，比较遗憾没能用起来。😔。大概思路如下所示：
<img src="https://i.loli.net/2018/03/20/5ab10f0c3255e.jpeg" width = "100%" height = "100%" align=center />

简单过一遍（怕又被警告实在是不敢贴源码了），`ONEProgressHUD`提供designated和secondary初始化方法，而且把能够给Coder自定义HUD的属性全都暴露出来了。在初始化方法中，非常简单的只是创建内存，初始化frame，addSubview到self中，重点在于有个`show`方法，在`show`方法中会先做判断是否有做延迟显示，如果没有的话，手动调用了`[self setNeedsDisplay]`方法，并且重写了`layoutSubviews`系统方法。`layoutSubviews`均不能被显式调用，而系统去调用`layoutSubviews`的时机有：①UIScrollView及其子类滚动时调用；②屏幕旋转时调用；③改变view.frame时调用。因此`ONEProgressHUD`在`layoutSubviews`方法中写明了所有有关label和indicator的位置约束信息，若当前有新的HUD信息需要展示时，可以重新对labelText进行赋值，然后再重新调用`show`方法即可通过触发`layoutSubviews`方法进行视图刷新。

`ONEProgressHUD`的HUD背景本身是通过调用`CoreGraphics`核心绘图库进行绘制的，这也保证了在各种手机尺寸下的准确性。最终拿去用的并不是`ONEProgressHUD`本身，而是他的一个category——`ONEProgressHUD+Custom`，该分类的各种方法就是基于`ONEProgressHUD`中的各种方法结合而成，给我自己的感觉，从未想到一个HUD中居然还能隐藏如此多的小细节~下一波的源码是`ONEAlertView`，下边就是`ONEProgressHUD+Custom`的一个例子。
<img src="https://i.loli.net/2018/03/20/5ab1133f3297c.png" width = "40%" height = "40%" align=center />

记录几个遗忘点：
1. `clang diagnostic`宏可帮助禁止clang编译器打出的优化意见，毕竟警告太多真的很烦
2. `NSParagraphStyle`熟悉能够设置Label的一些段落样式
