好久没在这边更新了,最近闲下来的时候把以前项目重构了,于是想分享一个简单的功能,废话不多说,今天就给大家带来仿照支付宝首页滑动并拓展
老样子,先来张效果图
其实我看了几个博主写过类似的功能,但是感觉功能自己的思路,
于是就花了半天写了个Demo,因为是Demo,
所以...我写的代码可能有一丢丢的乱.需要看的话我在最后面添加git链接.
整体思路
这种实现的思路基本差不多
控制器里添加一个整体的ScrollView,然后将该ScrollView的手势替换成你需要使用的手势,这里需要使用的手势是TableView的手势,
然后在主ScrollView上通过手势来滑动子视图TableView.
滑动的时候,监听TableView的偏移量.通过偏移量来改变HeaderView的frame,(这里的HeaderView不是tableHeaderView哦,别弄错了),因为我们的主ScrollView需要添加两个部分,头部和主干部,头部就是HeaderView,主干由于是多个UITableView.所以用子ScrollView添加这些UITableView.
因为我需要控制器添加主的ScrollView,所以我继承UIScrollView,将这些所有子视图都添加在里面了.
这里先上一下代码:
#import "QHScroll.h" // 继承UIScrollView
#import "MJRefresh.h"
#import "BackCell.h"
@interface QHScroll () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UIView *headerView; // 头部视图
@property (nonatomic, strong) UIScrollView *scrollView; // 子ScrollView
@property (nonatomic, strong) NSMutableArray *datas; // 数据
@property (nonatomic, strong) NSMutableArray<UIColor *> *colors; // 颜色
@property (nonatomic, strong) NSMutableArray<UITableView *> *tableViews;
@property (nonatomic, strong) NSMutableArray *gestures; // 存放多个tableView的手势数组
@end
然后就是初始化的时候添加所有控件:
[self addSubview:self.scrollView];
[self addSubview:self.headerView];
for (UITableView *tableV in self.tableViews) {
[self.scrollView addSubview:tableV];
[self.gestures addObject:tableV.gestureRecognizers];
}
self.scrollView.contentSize = CGSizeMake(kScreenWidth * self.tableViews.count, 0);
[self removeNowGestureRecognizerToAddNewGestureRecognizers:self.gestures[0]];
这里的 removeNowGestureRecognizerToAddNewGestureRecognizers:
方法就是替换手势,我把他写成方法了,因为在切换A,B,C三个UITableView的时候,需要对应的手势替换到主ScrollView上,
这里还需要注意的是,我之所以用gestures来先把多个UITableView的手势添加进去,是因为,直接将tableView的手势加到主ScrollView上会自动释放.导致手势消失,所以用了数组添加这些手势
替换手势的方法实现为:
- (void)removeNowGestureRecognizerToAddNewGestureRecognizers:(NSArray *)gestureRecognizers {
//移除主scrollView原有手势操作
NSMutableArray *list = [NSMutableArray arrayWithArray:self.gestureRecognizers];
for (UIGestureRecognizer *gestureRecognizer in list) {
[self removeGestureRecognizer:gestureRecognizer];
}
//将需要的手势操作加到主scrollView中
for (UIGestureRecognizer *gestureRecognizer in gestureRecognizers) {
[self addGestureRecognizer:gestureRecognizer];
}
}
手势问题就解决了.
然后就是监听tableView的偏移量了.这里用到了KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (change[@"new"]) {
CGPoint point = [(NSValue *)change[@"new"] CGPointValue];
if (point.y<=-200) {// 下拉
[UIView animateWithDuration:0.25 animations:^{
self.headerView.mj_origin = CGPointMake(0, 0);
}];
} else if (point.y >= 0) {
[UIView animateWithDuration:0.25 animations:^{
self.headerView.mj_origin = CGPointMake(0, -200);
}];
} else {
self.headerView.mj_origin = CGPointMake(0, -200 - point.y);
}
currentChangeY = point.y;
}
}
这里有个-200的值,这也是我想的另一种方法来实现滑动到顶部的时候cell点击问题.设置的代码为:
tableView.scrollIndicatorInsets = UIEdgeInsetsMake(200, 0, 0, 0);
tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0);
放一张视图层的状况应该能了解了
这里我把子ScrollView的frame设置除去导航高度的大小,然后tableView设置比他小40高度,40高度预留的是为了让头部视图最下面高度40的地方能悬停,如果不需要悬停40,就可以设置成子UIScrollView一样大小wwww
上下滑动也就差不多这样,具体可以看我github上的代码.
然后就是左右滑动...大家应该都了解到网易的pagesController,我这里没用到这些,只是做了简单的偏移判定,然后在我的项目里是自己写的,后续会分享出来www
这里的效果不推荐使用上面tags点击和下面tableView联动封装在一个界面的.因为要达到我上面那个效果,需要把视图上的"添加tags点击"这个label换成tags就行了,而且是和下面子ScrollView分开的.这样可以在上拉的时候直接修改headerView的frame了.
左右滑动的代理是用了子ScrollView的scrollViewDidScroll:方法,这里面来修改tableView显示,如果加了tags,可以自己添加联动wwwww
差不多就这样啦.希望大家会喜欢😝
点击前往demo页面,如有帮助,不妨来个star😉w
有问题欢迎在评论区提问w