商品详情页多个列表滑动效果实现方案

近来项目功能重新拆分,主要负责商品详情模块,于是乎看了一下之前代码,真是一片混乱,遂决定应用MVVM+RAC重构下。

首先看一下下面四张截图,了解下想要实现的效果。因为淘宝天猫等客户端已经对商品详情页大改版,找不到之前的截图了,用美丽说的页面举个例子。




整个页面的结构是这样的:上面是一些商品的基本信息,中间是三个tab标签,下面对应每一个标签又有一些针对商品的信息。

于是很自然想到四个商品信息页分别单独做成一个tableView,tab切换做成一个view。但是怎么样能实现tableView套tableView呢,难点在于三个tab间不光要实现点击切换还要实现滑动切换,这就必须要使用scrollView了。

第一种思路是将下面的tableView融合进上面的。

具体实现有两种方式:

1 整体是一个tableView,将下面tab切换view以及scrollView封装进一个大cell,scrollView上面是三个子tableView,分别显示对应标签的内容。使用时将这个cell放到整体tableView的最后一个即可,高度设置为tableView的高度。难点在于针对tab是否达到页面顶部控制cell中的几个tableView是否可以滚动。
具体实现的话可以在

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

方法中做判断,然后在内外两层view中发送通知,虽然代码结构不是很优雅,但是也算是大致实现了。只是这种方式有一个硬伤无法解决:内外两层tableView导致会有两个系统自带的提示条,分别指示各自的高度,无法指明整体view的高度。

2 仍然整体是一个tableView,将下面tab切换view以及scrollView封装进一个大cell,scrollView上面是三个子tableView,分别显示对应标签的内容。使用时也是将这个cell放到整体tableView的最后一个,区别在于首先将tableView设置为不可滚动,其次对这个cell的高度不再设置固定值,而是提前根据需要显示的内容计算出全部显示的高度,即tableView的contentSize.height,当然针对三个不同的标签会有三个值,每次切换的时候reload一下,将cell高度设置成里面当前正在显示的tableView.contentSize.height,此时系统自带的提示条也会指示正确的大小及位置,解决了上面1中的硬伤。然而,这却导致了另一个硬伤无法解决:当三个不同标签对应的三个tableView内容高度相差很多时,滑动时会出现一个列表有内容而另一个列表无内容只能显示背景色的尴尬。

鉴于上面第一种思路总有无法解决的问题,我意识到应该是思路错了。于是有了下面的。

第二种思路是将上面的tableView融合进下面的。

整体是一个scrollView,铺满全屏幕,上面是三个包含tableView的子view,分别显示对应标签的内容。最上面的tableView不可滚动,且是下面tableView的tableHeaderView,tab切换view是下面tableView的sectionHeaderView。这样避免了手动计算高度的复杂性。当点击tab或者滑动scrollView切换列表时,先将这两个view从原来的父视图上删除,然后加到controller的view上,切换完成的时候再加到当前显示的tableView上。这些都可以通过代理方法实现。几个单独封装的视图大概如下:

@property (nonatomic, strong) UIScrollView *fullScrollView;
@property (nonatomic, strong) GDUpGeneralInfomationView *upInfomationView;
@property (nonatomic, strong) GDMiddleTabSwitchView *tabSwitchView;
@property (nonatomic, strong) UIView <GDDownInfomationViewProtocol>*currentInfoView;

第一种思路中出现的问题全部解决,更重要的是保持了几个视图的独立性和完整性,很方便拓展功能或者复用。

更多的实现细节就不说了,项目完整版地址请猛戳这里