iOS一些外卖APP中经典的两个TableView滑动效果

废话少说,先看效果:
01.gif

文章最后会有demo地址!

实现思路

首先,从界面上来看,很显然是两个UITableview上下滑动的效果。而这种滑动的效果核心是左边的tableView如何和右边的tableView进行关联,并且点击左边tableView之后右边的tableview也可以滑动到对应的section
好了,分析完毕之后,我们应该清楚了我们的2个需求:
1.当点击左边TableViewCell时候,右边TableView会跟随着滑动到对应的section
2.当滑动右边TableView时候,左边TableView会根据右边UITableViewsection滑动到对应的UITableViewCell位置

实现步骤

第一个需求

1.当点击左边TableViewCell时候,右边TableView会跟随着滑动到对应的section

1.左边UITableViewdidSelected方法

#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会根据右边UITableViewsection滑动到对应的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地址

https://github.com/JimmyLession/TwoTableViewSlideDemo.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容