首发: http://www.jianshu.com/p/42a84c9079c1
不知不觉就成了UITableView的重度患者,应对各种需求(比如换顺序、按条件显示内容、插广告、各处插广告)真是舒心。
但是近来随着使用渐多,某些情况也显得捉襟见肘起来:
问题一:首先是老大难 auto layout
使用auto layout的过程中,我始终觉得苹果欠我们一个auto layout的初设函数:要求其在view frame初始化后,且view还未显示时被调用;
先说说UIViewController
- 对UIViewController而言,比较推荐的auto layout的初设函数是
viewDidLoad
(见这个回复:Where should I be setting autolayout constraints when creating views programatically)。然而在viewDidLoad
中,view的frame并未得到初始化,部分依赖于实际尺寸的constraint又该如何设置呢? - 还有一种做法是选用
viewDidLayoutSubviews
作为auto layout的初设函数,这里满足上面说的两个条件,但是需要加上一个标志位,用来判定是不是第一次(view还未显示时)调用。丑爆了!
回到UITableViewCell
对于Cell而言,auto layout的初设函数应该选用哪个?比如下例:
cell上有一个view,要求在3.5寸屏上的大小为36x36,在4寸屏上的为50x50,在4.7寸屏上为60x60,在5.5寸屏上位68x68(别问为什么,就是这么任性)。这个constraint如何设置?
很多人会说layoutSubviews
,然而:
- 同
viewDidLayoutSubviews
,要在layoutSubviews
中判断是否为初次加载,需要额外参数一枚
- iOS9上,
layoutSubviews
有bug,见我的帖子,layoutSubviews
在cell加入view hierachy之前就被dequeueReusableCell......所调用了,简直不可原谅。
问题二:其次是逐渐增多的动画效果
动画的需求和上面提到的auto layout的初设函数有些类似,同样需要:
- 初始化后的frame
- 明确的timing:cell显示在屏幕上以后
由于和问题一类似,就不展开了。
解决问题的思路
在思考如何解决上述问题的过程中,特别是cell的layoutSubviews在iOS9上的问题,使我不得不考虑寻求另外的函数入口。
自然而然,我想到了UIViewController的生命周期函数,暂时称之为Lifecycle events吧。viewWillAppear, viewDidAppear, viewDidLayoutSubviews之类的回调函数,使我们可以从容的布置代码。
为了实现这个目标,需要找到跟cell生命周期相关的各种函数,比如定义在UITableViewDelegate中的tableView:willDisplayCell:forIndexPath:
以及tableView:didEndDisplayCell:forIndexPath:
。在这两个函数中触发cellWillAppear
以及cellDidDisappear
,不能更赞!然而这两个是optional delegate,并没有具体的实现,如何加以利用呢?