(一) 按照当前发展趋势,苹果不断的完善storyboard使其能完成大多数代码可以完成的工作,那么为什么要用手写代码方式制作UI呢
1.1 用sb,或者xib创建的应用程序,在编译期间很耗费时间,xcode需要把xib文件一个个转换成可以理解的代码
1.2 另外interface工具生成的xib,不支持继承,加入我们有一个cell要在不同地方利用,但是每个cell的改动很少,那么我们用xib是不是要 回执每一个cell,虽然是用command c + command v,但是如果后期我们需要每个cell的共同属性都改动一下呢,这...
1.3 纯代码方式可以完美解决上面问题,而且加入了另一个优秀特性,易于管理,可以抽出来公共模块,加以利用或者直接用继承+ 稍微的修改, 并且可以在很多地方进行复用代码..... 还有可以创建xib库里面没有的一些组件,以及效果这些都是利用纯代码的有点, 并且有篇文章专门进行了 当下流行app测试,发现 微信,等很知名的公司,里面xib数量很少,反而是一些创业公司,里面xib很多,这也证明了xib的便利性,但是随着项目的发展, 后期的迭代,xib等会显现出来他的缺点..
(二) 那么话说回来,如何实现,以及最优实现呢?
如何实现,这个不需要我多讲,应为开发过苹果程序,或者可以说初步接触如何变成程序的时候我们都是接触的代码编写程序, 界面也是代码编写出来的, 至于后面为什么出了可视化工具,是为了解决一些在UI上面我们浪费太多时间的问题, 那么,如果我们能在UI上面浪费极少的时间用代码去代替可视化工具实现, 那么这就是 我理解的最优实现, 既保留了代码的灵活性,又 不是 类似 可视化工具一样的 速度性,便利性
好吧:开始代码创建UI思路
---------------------
2.1 首要问题是布局问题, frame,绝对布局这个可以说很少人用了吧,但是在某些地方还是有用处的, 建议在某些用frame就能完成的很微小的地方,直接frame,解决,不需要用 autolayout
2.2 autolayout自动布局,我们有大体上有三类实现自动布局手写代码的方式, 手写排除xib中的拖线方式,不在我们的手写代码考虑范围之内,
1. 苹果原生的, 一条约束一大坨子的 a = b * x + c 这个恐怕是因为太长令人头疼的吧, 这个建议在写一些框架的时候,如果实在需要,可以用这个,因为 利用框架的人不一定有你所导入的三方库,这个也适用于VFL
2 苹果原生的,VFL语言,大家戏称为外星文, 约束代码行数是减少了,但是不太容易理解,不直观,以及灵活性没那么高
3 三方库, 推荐SnapKit 等知名的自动布局库, 这些库呢可以说是把系统的原生约束代码,包装一下,用一种更简单直观的方式写出来布局,这个是非常好的
2.3 布局解决完了,那么我们加入有些UI效果是和我们当下布局有冲突怎么办?
1. 目前为止我也只是大致碰见了两类这种问题,第一种是 scrollView嵌套tableView ,只滚动外部scrollView,但是内部tableView也要完全动态的加载的问题.
这个怎么解决.... 查看苹果官方文档, 看到是推荐用constriant, 但是往下看,在 layoutSubViews 或者 viewDidLayoutSubViews ,一个是view的获取真实布局frame的地方,另一个是vc获取真实布局frame的地方,这两个地方可以做出我们需要的特殊效果,
为什么会是在这里呢,苹果文档里面含有了,这里面是调取约束,约束最终计算的一切会在这里得出每个视图真实的frame最终显示出来,那么解决办法来 了,在tableView的layoutsubView里面, 当tableView的contentSize不和tableView的frame相等的时候,也就是tableView即将滚动,我们把 tableView的frame高度设置为何内容高度一样,那么tableView就不能滚动了, 那么外部scrollView呢,很简单吧scrollView的contentSize高度设置成 tableView的 ,origin.y + tableViewcontentSize的高度,那么外部scollView的内容也同等的扩大了, 但是外部scrollView的frame却没有扩大,所以会看到外部scrollView滚动了, 最后又个问题是 超出scrollView原本内容的tableView的cell竟然无法点击...... 想想这是怎么回事? 很简单,我们的view,也就是vc的视图的frame还是保持着和原来一样,我们把view的frame也扩大和scrollView的内容扩大一 致,则可以正常点击..... 话说回来我们分析一下,在vc单独添加tableView这样的模式里,我们并没有刻意的去设置view的frame和tableView的内容同步,自 己就能点击超出范围的内容, 这...应该是系统自动变更了view的frame,或者更可以说是 ,我们在scrollView上加tableView,默认最终vcView的frame是以我们scrollView确定的contentSize来变 更frame的, 但是我们动态的改变了scrollView的contentSize,view的frame还没改变,这就是最终的原因
2 另一个就是scrollView里面的某一个view悬停的问题
也是在layoutSubViews里面,我们找到我们需要悬停的view, 然后做一个判断,当scrollView的offset 在我们设定的阈值的时候,给这个 悬停view一个frame,当超出我们的阈值的时候给这个悬停view另一个frame, 也许你会问为什么会达到这种效果, 我可以说是苹果layout底层调用到layoutSubViews去寻找每个view的布局frame,我们在这里做一些特殊运算,可以说是hook了 苹果的底层对开发者开放的接口,这个layoutSubViews是会多次调用的, 而且放心,这是苹果推荐的做特殊效果的接口,而且不是私有的, 不会对我们发布app有任何影响
...话说回来其实苹果并不建议scrollview嵌套类似scrollview的UI控件,因为滚动的问题.实际上能用简单tableview这样一个控件实现的不要多层嵌套,影响性能,而且增加了复杂度,不符合简介设计..
...其实最近在写个小项目,发现用约束和frame结合起来计算还是不错的,有些小的地方需要循环添加的frame几句话搞定,外部如果用约束也不会出错. ...但是前提是,计算frame必须以在layoutsubview或者viewwilllayoutsubview中,因为这两个方法调用之前,是先布局约束,计算过frame的,所以在这两个方法之间是完全可以拿到self 的frame的.我一般的做法是 在这两个方法中基于 本身的bouds计算子sub的frame,方便简单
因为这个这两个方法可能调用多次,但是frame一般只需要计算一次,那么我会加一个判断类似下面
if xxx.frame == CGRectZero {
.......
}
里面计算基于self的bouds的子subframe.而且只计算一次,发现真实简洁好使.如果需要动态的计算例如label不同文字的frame,一般是抽出来个方法,在这两个方法里面是有,以及在set 新值得时候再计算下frame搞定...
说了这么多不外乎哪个更方便,我觉得frame还是挺方便的,和约束结合起来事半功倍....