废话少说,先看效果:
文章最后会有demo地址!
实现思路
首先,从界面上来看,很显然是两个
UITableview
上下滑动的效果。而这种滑动的效果核心是左边的tableView
如何和右边的tableView
进行关联,并且点击左边tableView
之后右边的tableview
也可以滑动到对应的section
好了,分析完毕之后,我们应该清楚了我们的2个需求:
1.当点击左边TableViewCell
时候,右边TableView
会跟随着滑动到对应的section
2.当滑动右边TableView
时候,左边TableView
会根据右边UITableView
的section
滑动到对应的UITableViewCell
位置
实现步骤
第一个需求
1.当点击左边
TableViewCell
时候,右边TableView
会跟随着滑动到对应的section
1.左边UITableView
的didSelected
方法
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//_rightVC 右边TableView子控制器对象
if (_rightVC) {
// 子控制器封装的方法
[_rightVC leftTableViewToSelectedAtIndexPath:indexPath];
}
}
2.右边UITableView
封装方法的实现
//点击左边tableViewCell 滚动时 右边tableView一起滚动
- (void)leftTableViewToSelectedAtIndexPath:(NSIndexPath *)indexPath
{
[self.rightTableView selectRowAtIndexPath:([NSIndexPath indexPathForRow:0 inSection:indexPath.row]) animated:YES scrollPosition:UITableViewScrollPositionTop];
}
第二个需求
2.当滑动右边
TableView
时候,左边TableView
会根据右边UITableView
的section
滑动到对应的UITableViewCell
位置
1.右边UITableView
.h文件
@protocol ScrollAtSectionDelegate <NSObject>
//制定代理
- (void)willDisplayHeaderView:(NSInteger)section;
- (void)didEndDisplayingHeaderView:(NSInteger)section;
@end
@interface RightClildViewController : UIViewController
//代理属性
@property(nonatomic, weak) id<ScrollAtSectionDelegate> delegate;
@end
2.右边UITableView
.m文件
#import "RightClildViewController.h"
@interface RightClildViewController ()<UITableViewDelegate, UITableViewDataSource>
/**
* 结束滚动时的偏移量
*/
@property(nonatomic, assign)CGFloat endScrollOffset_Y;
/**
* 是否可以向上滚动
*/
@property (nonatomic ,assign)BOOL isUpScroll;
/**
* 右边的tableView
*/
@property (nonatomic ,strong)UITableView *rightTableView;
@end
- (void)viewDidLoad {
[super viewDidLoad];
_isUpScroll = NO;
_endScrollOffset_Y = 0;
self.view = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width * 0.25, 64, self.view.frame.size.width * 0.75, self.view.frame.size.height-64)];
[self.view addSubview:self.rightTableView];
}
//在这里只贴出了 核心代码
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
_isUpScroll = _endScrollOffset_Y < scrollView.contentOffset.y;
_endScrollOffset_Y = scrollView.contentOffset.y;
}
/**
* 这两个方法从字面意思上就可以看出来 是在页眉将要出现和页眉移动屏外
* 会调用的方法
* tableView的isDecelerating属性
* 返回YES 用户没有触摸滚动tableView 但是tableView还是会移动
* 返回NO 反之
*/
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
if (self.delegate && [self.delegate respondsToSelector:@selector(willDisplayHeaderView:)] != _isUpScroll &&_rightTableView.isDecelerating) {
[self.delegate willDisplayHeaderView:section];
}
}
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section {
if (self.delegate && [self.delegate respondsToSelector:@selector(didEndDisplayingHeaderView:)] && _isUpScroll &&_rightTableView.isDecelerating) {
[self.delegate didEndDisplayingHeaderView:section];
}
}
3.左边UITableView
.m文件
#import "JMSlideView.h"
#import "RightClildViewController.h"
@interface JMSlideView ()<UITableViewDelegate,UITableViewDataSource,ScrollAtSectionDelegate>
/**
* 该View对应所在的控制器
*/
@property (nonatomic ,strong)UIViewController *parentVC;
/**
* 右边 子控制器
*/
@property (nonatomic ,strong)RightClildViewController *rightVC;
/**
* 左边 tableView
*/
@property (nonatomic ,strong)UITableView *tableView;
/**
* 左边tableView 数据源
*/
@property (nonatomic ,strong)NSMutableArray *dataArray;
/**
* 右边tableView 数据源
*/
@property (nonatomic ,strong)NSMutableArray *rightArray;
@end
@implementation JMSlideView
static NSString *const leftIdentifier = @"leftIdentifier";
- (instancetype)initWithFrame:(CGRect)frame
leftDataArray:(NSMutableArray *)leftDataArray
rightDataArray:(NSMutableArray *)rightDataArray
{
self = [super initWithFrame:frame];
if (self) {
self.dataArray = leftDataArray;
self.rightArray = rightDataArray;
[self addChildViewController];
[self addSubview:self.tableView];
}
return self;
}
//添加子视图控制器
- (void)addChildViewController
{
self.rightVC = [[RightClildViewController alloc]init];
[self.parentVC addChildViewController:_rightVC];
self.rightVC.headerArray = self.dataArray;
self.rightVC.rightArray = self.rightArray;
self.rightVC.delegate = self;
[self addSubview:_rightVC.view];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:leftIdentifier];
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:13];
return cell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_rightVC) {
[_rightVC leftTableViewToSelectedAtIndexPath:indexPath];
}
}
#pragma mark - ScrollAtSectionDelegate
- (void)willDisplayHeaderView:(NSInteger)section {
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
- (void)didEndDisplayingHeaderView:(NSInteger)section {
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section + 1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
外部调用
#import "ViewController.h"
#import "JMSlideView.h"
@interface ViewController ()
{
NSMutableArray *leftDataArray;
NSMutableArray *rightDataArray;
}
@property (nonatomic ,strong)JMSlideView *slideView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
leftDataArray = [NSMutableArray arrayWithObjects:@"热销菜品",@"精选组合",@"粥类",@"东北小町米",@"特色佳肴",@"商务套餐",@"开胃冷菜",@"热菜大荤",@"汤类",@"酒水饮料", nil];
rightDataArray = [NSMutableArray arrayWithObjects:@"米饭",@"小炒花菜",@"黑木耳炒山药",@"红烧鸡腿",@"农家小炒肉",@"板栗烧鸡", nil];
[self.view addSubview:self.slideView];
}
- (JMSlideView *)slideView
{
if (!_slideView) {
_slideView = [[JMSlideView alloc]initWithFrame:self.view.bounds leftDataArray:leftDataArray rightDataArray:rightDataArray];
}
return _slideView;
}
总结
这种类似的滑动效果在一些外卖APP中经常会看到。要实现这种滑动效果其实并不难,主要能把思路捋清楚就会有另一番收货。比如tableView
这些不常用的代理方法及属性,如果可以多了解下,运用到实际的项目中就会有意想不到的效果。
大家加油,共同学习!!!
本文demo地址