模仿朋友圈的做法、重温collectionView流布局、CHTCollectionViewWaterfallLayout

第一次学习:

GSD_Weixindemo 研究

1、SDDiscoverTableViewController

是发现页面

SDTimeLineTableViewController

SDWeiXinPhotoContainerView 微信图片容器视图

点击粗发的视图

- (void)tapImageView:(UITapGestureRecognizer *)tap

优秀可以学习文章:

iOS基于MVVM+RAC + viewModel-based navigation 的微信开发

1、https://www.jianshu.com/p/fd407a4ecb8e

iOS基于MVVM设计模式的微信朋友圈开发

2、https://www.jianshu.com/p/2f161f6a310f

雷纯锋技术博客文章

3、http://blog.leichunfeng.com/

微信朋友圈评论回复功能

4、https://www.jianshu.com/p/395bac3648a7

5、发现最具代表性的两个Demo分别是:gsdios/GSD_WeiXinzhengwenming/WeChat

文章阅读笔记:

1、红框包含绿框,红框是一个uitableveiwcell

2、这样就会涉及到当用户滚动朋友圈列表且cell复用的时候,绿框②内部的子控件的个数也是动态的,可能增多,又可能减少,这样就造成了动态增加或删除绿框②内部的子控件,想必大家都知道尽量不要在UITableViewCell中动态创建子控件,这是比较耗性能的,常规的做法都是事先在

3、但是由于朋友圈列表的每条说说的评论列表个数是不能事先确定的,所以必然会存在绿框②动态创建子控件的悲剧。

4、对于上面动态创建控件的问题,其实该作者在内部SDTimeLineCellCommentView.h/m也是做了优化处理的。

这个里面是可以看布局的,也是可以看cell的创建过程的。

5、优酷视频的评论回复(如下图)。这个方案也不失为一个好的解决方案。所以说业务场景不同,实现方案不同,可见在敲代码之前,先思考后确定实现方案是多么重要。

6、内部实现说到底其实就是充分利用UITableView的特性,选取不同UITableViewCell来显示点赞列表和评论列表而已,相比于方案一来说,该方案主要发挥出了UITableView的特性,通过实现UITableView的协议方法就能实现评论和点赞列表的展示,且实现起来更加简单易懂,这可能是目前市场上绝大多数的做法。

7、虽然外表看似毫无破绽,但是其中隐藏巨大弊端。之前笔者也利用这种方案,写过类似微信朋友圈的评论回复,详情请参考:iOS 实现微信朋友圈评论回复功能(二),但是其中存在的问题,笔者却没有叙述,实属抱歉,当然这里笔者将详述其存在弊端和产生的原因,以及让大家重新加深对UITableView的理解。弊端如下:

8、当然最主要的还是考察技巧性(黑魔法)

9、①考虑到微信朋友圈这一个硬需求,笔者着重从性能上出发,第一想到的就是利用Cell的复用机制来展示每条说说的评论内容;②考虑到前两个方案都是把红色框①当做一个整体来处理,且都来了类似的弊端以及针对评论内容大数据所带来的性能问题,以免重蹈覆辙,笔者将红色框①拆分为下图几个模块:一条说说(红色框①) = ()头(绿色框②) + Cell(紫色框③) + 组(段)尾(黑色框④)

这确实又很大创新

10、通过上图所示,虽然该方案在模块划分上是比较的分散,但是其总体带来的性能是非常客观的,大大保证了朋友圈列表滚动的流畅性。其中当然最最主要的原因还是归功于上图所示的组(段)头(绿色框②)、Cell(紫色框③)、组(段)尾(黑色框④)这三个控件都是可以通过使用TableView的数据源方法以及代理方法(代码如下)轻松实现View的复用机制的,而且都是平常开发中常用的方法,这样前面两个方案所存在的弊端就迎刃而解了。

11、首先平常开发过程中,Cell的宽度一般是跟所处的tableView的宽度是一致的,但是微信朋友圈里面的这个评论Cell明显不是,这里笔者需要强调的是:重写是个好东西。这里的关键点就是在于重写自定义的UITableViewCell的- (void)setFrame:(CGRect)frame方法

 

第二次学习:

1、流水布局,可以理解为,怎么合理设置约束,采用可以重用的方式

2、流失布局是从左到右开始,一边一边累积,然后在往下面累积。

3、流水布局跟瀑布流又不一样的

4、不管多少列,流动布局的规则是从左到右排列,每列cell宽度一致,但是高度不一,第一行排完后,紧接着第二行,第二行的首先要找到一个cell的maxY最小的,从这个地方开始,接着就是剩余的最小的,不是第一行那样依序排列。这样做是为了能尽量填满空间。选找空位是根据列高最小开始,但是计算视图高度,就是要找列里面最高的列。

5、不管是多少列,视图总是能自适应,是因为CHTCollectionViewWaterfallLayout内部计算了section的高度。

 

1、下面内容是链接内容的笔记,感谢作者。

https://www.jianshu.com/p/40868928a1cf 

2、你所想实现的外观并不是网络或者line-based breaking 布局(items排成一行直到行满,再继续往下一行去排,直到所有的items都排列完成)或者必须要在多个方向上都可以滚动。

3、需要频繁地改变所有 Cell的位置,以致于创建自定义layout比修改现有flow layout工作量更省

4、自定义最难的部分是确定布局中各item位置所需要的计算

5、invalidateLayout方法义更新布局对象,此方法会强制生成新的layout.

6、需要注意invalidateLayout与reloadData的区别,在移动,添加或者删除item的时候,需要摒弃原有布局,重新生成新的布局,使用invalidateLayout,而如果只是datasource中的数据有更新,这时需要使用reloadData

7、prepareLayout方法调用来为即将进行的layout作前期的计算

8、layoutAttributesForElementsRect方法返回指定区域中cells和views的属性

9、prepareLayout方法是为确定布局中各cell和view位置做计算,需要在此方法中算出足够的信息以供后续方法计算内容区域的整体size

10、collection view使用content size以正确地配置scroll size.比如 content size长宽均超过屏幕的话,水平与竖直方向的滚动都会被enable.

11、基于当前滚动位置,collection view会调用layoutAttributesForElementsInRect:方法以请求特定rect(有可能是也可能不是可见rect)中cell和view的属性。到此,core layout process已经结束了。

12、lauout 结束之后,cells和views的属性在你或者collection view invalidate 布局之前都不会变的,collection view可以在滚动的过程中自动invalidate布局:用户滚动内容过程中,collection view调用layout的shouldinvalidateLayoutForBoundsChange:方法,如果返回YES则invalidate布局。

13、但需要知道的是,invalidateLayout并不会马上触发layout update process,而是在下一个view更新周期中,collection view发现layout已经dirty才会去更新

14、自定义layout需要创建UICollectionViewLayoutAttributes类的对象,这些对象可以在很多不同方法创建,但创建时间可以根据具体情况具体决定。

15、如果collectionview未有数千的item,则prepare layout时创建会比在用户滚动过程中用到时再计算更可取,因为创建的这些属性可以缓存起来。

16、如果计算所有属性并缓存起来所带来的性能消耗比请求时获取的消耗更大,则可请求时再创建相关属性对象。

17、基于展示view类型的不同,必须使用正确的类方法,因为collection view使用这些信息向datasource对象请求适当类型的view。使用错误的方法会引起collection view在错误的地方创建错误的view,你所希望呈现的layout就不会出现。

18、创建每个属性对象之后,将相应View的相关属性都设置上。最少要在layout中设置view的size和position。如果在你的布局中有view重叠了,需要正确配置zIndex属性以维持重叠views的一致的有序状态。其他属性可以让你控制cell或者view的可见性或者外观表现。如果标准属性类无法满足你的需要,可以继承并对其进行扩充以存储每个View的其他信息。继承layout属性时,需要实现属性的isEqual:方法因为collectionview需要使用这个方法。(这段没读懂)

19、layout process的最后,collection view会调用你的layout对象的layoutAttributesForElementsInRect:方法,对一个大的可滚动的内容区域,collectionView可能只会请求当前可见的那部分区域的所有items的属性。当然,这个方法需要支持获取任意rect中items的信息,因为有可能在插入和删除时需要做动画效果。

20、layoutAttibutesForLementsInRect;方法的实现需要遵循如下步骤:

(1)遍历prepareLayout方法产生的数据以访问缓存的属性或者创建新的属性

(2)检查每个item的frame以确认是否与layoutAttributesForElementsInRect方法中指定rectangle有重叠的部分

(3)对每个重叠的item,添加一个对应的UICollectionViewLayoutAttributes对象到一个数组中

(4)返回布局属性的数组给collection view

20、不仅要记住缓存layout信息能够带来性能提升,也要记住不断重复为cells创建新layout属性的计算代价是十分昂贵的,足以影响到app的性能。当collection view管理的items量很大时,采用在请求时创建layout属性的方式是十分合理的。

21、返回属性时,不能更新这些layout属性,如果需要改变layout信息,调用invalidateLayout,在接下来的layout周期中更新这些信息。上述方法中layoutAttributesForItemAtIndexPath:是所有自定义 layout都必须重载的方法,如果有supplementary view和decoration view可以分别重载下面两个方法。

没读懂的

22、supplementary views与Cells分离且有自己的layout属性,由Datasource提供,且其目的是为app主要内容增强信息。与cells一样,supplementary view也会经历重用的过程以最小化collection view使用的资源消耗。所以所有 supplementary view都需要继承UICollectionReusableView。

23、实现layoutAttributesForSupplementaryViewOfKind:atIndexPath:方法为特定supplementary View返回属性对象

24、Decoration Views是layout UI特征的有效点缀,与cell和supplementary view不同的是,它只做外观呈现用,所以与datasource无关。可以用来提供自定义背影,在Cells缝隙之间填充,甚至可以掩盖cell,它完全由layout对象控制。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值