开发过程中,经常碰到有需求说要当页面下,有多个可点击,可滑动切换的视图。如网易新闻的首页,部分app的个人信息页等。实现的思路可以是UIPageViewController多页面混合开发,或者addChildViewController的方式。
本篇讲的是另外一种方式,在自定义的scrollView上根据frame添加view,通过改变contentOffset达到更换视图的效果。一般情况下,可滑动的视图不会超过四个,为防止该功能每次需要的时候都要重写,就做了一个封装的SegmentContentView,可支持动态初始化,支持2~4个tableView的切换。
防止.h文件暴露出来的方法太多,所以只释放了需要一些属性和方法,初始化的时候,传入想要的tableView的数目创建view,selectFlagWithIndex该方法是在外部点击切换按钮,主动更改contentOffset,默认是没有加切换动画的。
@property (nonatomic, strong) UITableView * firstTableView;
@property (nonatomic, strong) UITableView * secondTableView;
@property (nonatomic, strong) UITableView * thirdTableView;
@property (nonatomic, strong) UITableView * fourthTableView;
@property (nonatomic, weak) id segmentDelegate;
/**
* 根据传入的数目,初始化视图
*/
- (instancetype)initWithFrame:(CGRect)frame tableViewCounts:(NSInteger)counts;
/**
* 根据头部点击按钮滑动到该tableView
*/
- (void)selectFlagWithIndex:(NSInteger)index;
以下是SegmentContentView必须实现的代理方法,是把view内部的tableView的dataSource代理放了出来,根据需求不同灵活更改
/**
* 外放cell数目
*/
- (NSInteger)creatCellWithTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
/**
* 外放自定义的cell
*/
- (UITableViewCell *)creatCellWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath;
以下是自定义的一些代理,因为本次开发中有一个根据滑动位移,需要把头像缩小到导航栏的需求,如果再碰到这种情况,可以根据tableView滑动的距离自行添加动画
/**
* 外放cell高度
*/
- (CGFloat)creatCellHeightWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath;
/**
* 外放头视图
*/
- (UIView *)creatHeaderViewWithTableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
/**
* 外放头视图高度
*/
- (CGFloat)creatHeaderViewHeightWithTableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
/**
* 滑动到另外一个tableView可以产生的回调
*/
- (void)scrollToOtherTableView:(UITableView *)tableView index:(NSInteger)index;
/**
* 针对tableView滑动外放的方法
*/
- (void)scrollWithTableView:(UITableView *)tableView;
以下是出来的效果
关于滑动位移改变,计算出具体位移改变量,滑动过程中,改变相应同比例数值,需要注意的点是scrollView的scrollViewDidScroll滑动代理,并不是逐帧执行的,在滑动过快的时候只通过代理回调,会出现掉帧的情况,尤其是在开始和结束的时候,一旦超出滑动范围,需要补调一次代理,设置需要的frame范围,用户体验会好很多。
这次需求要求的是头部缩放的滑动范围内,多个tableView也应当同步滑动,否则用户在切换不同的tableView时,因为头视图高度不一样而不美观,所以实际上看上去像是头视图的view,是添加在VC上的,与SegmentContentView同级,覆盖在tableView的透明头视图上,所以减少了创建四个头视图,避免了需要同步修改多个头视图状态的问题