自定义UITableViewCell实现左滑动多菜单功能LeftSwipe

  今天愚人节,小伙们,愚人节快乐!

  实现一个小功能,滑动菜单,显示隐藏的功能菜单, 先上图:

这里尝试用了下使用三个方式来实现了这个功能:

1、使用自定义UITableViewCell + UISwipeGestureRecognizer + 代理 实现;

2、使用自定义UITableViewCell + UIPanGestureRecognizer + 代理 实现;

3、使用自定义UITableViewCell + UISwipeGestureRecognizer + block 实现。

注意点: 使用UIPanGestureRecognizer手势实现左滑的时候,由于拖拽手势的方向随意性,导致与UITableViewController的下拉刷新手势冲突了!

感觉还是用UISwipeGestureRecognizer清扫手势实现好点!

部分代码:

1、使用UISwipeGestureRecognizer  +  Delegate 

自定义UITableViewCell部分代码:

 1 //
 2 //  TanTableViewCell.h
 3 //  Tan_SwipeTableViewCell
 4 //
 5 //  Created by PX_Mac on 16/3/25.
 6 //  Copyright © 2016年 PX_Mac. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 @class MemberModel;
11 @class TanTableViewCell;
12 
13 @protocol TanTableViewCellDelegate <NSObject>
14 
15 @optional
16 - (void)deleteMember: (TanTableViewCell *)cell; //协议方法:删除会员
17 - (void)closeOtherCellLeftSwipe;  //关闭其他单元格的左滑
18 
19 @end
20 
21 @interface TanTableViewCell : UITableViewCell
22 
23 //静态构造方法
24 + (instancetype)cellWithTableView: (UITableView *)tableView;
25 
26 @property (nonatomic, strong) MemberModel *model; //模型属性
27 @property (nonatomic, weak) id<TanTableViewCellDelegate> delegate; //代理
28 
29 - (void)setData: (MemberModel *)model; //设置要显示的数据
30 - (void)closeSwipe; //关闭滑动,恢复原样(用于在滑动当前单元格时,把其他已经左滑的单元格关闭)
31 
32 @end
@implementation TanTableViewCell

+ (instancetype)cellWithTableView:(UITableView *)tableView{
    static NSString *reuseIdentity = @"tanCell";
    
    TanTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentity];
    
    if (cell == nil){
        cell = [[TanTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentity];
    }
    return cell;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]){
        [self initSubControls]; //初始化子控件
    }
    return self;
}

//初始化子控件
- (void)initSubControls{
/*....... */

//3、给容器containerView绑定左右滑动清扫手势
    UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft; //设置向左清扫
    [self.containerView addGestureRecognizer:leftSwipe];
    
    UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;//设置向右清扫
    [self.containerView addGestureRecognizer:rightSwipe];
    
    self.selectionStyle = UITableViewCellSelectionStyleNone; //设置单元格选中样式
    [self.contentView bringSubviewToFront:self.containerView]; //设置containerView显示在最上层
}

//左滑动和右滑动手势
- (void)swipe: (UISwipeGestureRecognizer *)sender
{
    if (sender.direction == UISwipeGestureRecognizerDirectionLeft){
        if (self.isOpenLeft) return; //已经打开左滑,不再执行
        
        //开始左滑: 先调用代理关闭其他cell的左滑
        if ([self.delegate respondsToSelector:@selector(closeOtherCellLeftSwipe)])
            [self.delegate closeOtherCellLeftSwipe];
        
        [UIView animateWithDuration:0.5 animations:^{
            sender.view.center = CGPointMake(0, CELLHEIGHT * 0.5);
        }];
        self.isOpenLeft = YES;
    }
    else if (sender.direction == UISwipeGestureRecognizerDirectionRight){
        [self closeSwipe]; //关闭左滑
    }
}

//关闭左滑,恢复原状
- (void)closeSwipe{
    if (!self.isOpenLeft) return; //还未打开左滑,不需要执行右滑
    
    [UIView animateWithDuration:0.5 animations:^{
        self.containerView.center = CGPointMake(SCREENWIDTH * 0.5, CELLHEIGHT * 0.5);
    }];
    self.isOpenLeft = NO;
}

//.....
@end

控制器部分代码:

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    TanTableViewCell *cell = [TanTableViewCell cellWithTableView:tableView];
    cell.delegate = self;
    
    MemberModel *model = [self.dataArr objectAtIndex:indexPath.row];
    [cell setData:model];
    
    return cell;
}

#pragma mark - cell代理方法
//删除单元格
- (void)deleteMember:(TanTableViewCell *)cell{
    NSIndexPath *path = [self.tableView indexPathForCell:cell]; //获取cell所在位置
    //删除数组中数据
    [self.dataArr removeObjectAtIndex:path.row];
    //删除单元格
    [self.tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
}

//关闭其他cell的左滑
- (void)closeOtherCellLeftSwipe{
    //循环显示的cell
    for (TanTableViewCell *item in self.tableView.visibleCells) {
        [item closeSwipe];
    }
}

2、UIPanGestureRecognizer + 代理

自定义UITableViewCell部分代码:

 1 //初始化子控件
 2 - (void)initSubControls{
 3     /* ...... */
 4 
 5     //3、给容器containerView绑定拖动手势
 6     UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
 7     [self.containerView addGestureRecognizer:panGes];
 8     self.panGes = panGes;
 9     
10     self.selectionStyle = UITableViewCellSelectionStyleNone; //设置单元格选中样式
11     [self.contentView bringSubviewToFront:self.containerView]; //设置containerView显示在最上层
12 }
13 
14 
15 //拖动手势(拖拽手势和UITableView的下拉刷新手势有冲突,造成下拉刷新不能使用)
16 - (void)pan: (UIPanGestureRecognizer *)sender
17 {
18     //动画结束时修正位置
19     if (sender.state == UIGestureRecognizerStateEnded){
20         
21         //关闭其他cell的左拖拽
22         if ([self.delegate respondsToSelector:@selector(closeOtherCellLeftPan:)])
23             [self.delegate closeOtherCellLeftPan: self];
24         
25         if (sender.view.frame.origin.x < -SCREENWIDTH * 0.25){
26             sender.view.transform = CGAffineTransformMakeTranslation(-SCREENWIDTH * 0.5, 0);
27             [sender setTranslation:CGPointZero inView:sender.view];  //必须归0
28         }
29         else{
30             [self closeLeftPan];
31         }
32     }
33     
34     CGPoint point = [sender translationInView:self.contentView];
35     
36     CGFloat tx = sender.view.transform.tx;
37     
38     if (tx < - SCREENWIDTH * 0.5 || tx > 0) return;
39     
40     //形变
41     sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, 0);
42     [sender setTranslation:CGPointZero inView:sender.view];  //必须归0
43 }
44 
45 //关闭左拖拽
46 - (void)closeLeftPan{
47     self.panGes.view.transform = CGAffineTransformMakeTranslation(0, 0);
48     [self.panGes setTranslation:CGPointZero inView:self.panGes.view];  //必须归0
49 }

3、UISwipeGestureRecognizer + block 

自定义UITableViewCell部分代码:

 1 //
 2 //  TanTableViewCell.h
 3 //  Tan_SwipeTableViewCell
 4 //
 5 //  Created by PX_Mac on 16/3/25.
 6 //  Copyright © 2016年 PX_Mac. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 @class MemberModel;
11 
12 @interface TanTableViewCell : UITableViewCell
13 
14 //静态构造方法
15 + (instancetype)cellWithTableView: (UITableView *)tableView;
16 
17 @property (nonatomic, strong) MemberModel *model; //模型属性
18 - (void)setData: (MemberModel *)model; //设置要显示的数据
19 
20 @property (nonatomic, copy) void (^deleteMember)(); //删除会员block回调方法
21 @property (nonatomic, copy) void (^closeOtherCellSwipe)(); //关闭其他cell的左滑
22 
23 - (void)closeLeftSwipe; //关闭左滑
24 
25 @end
 1 //左滑动和右滑动手势
 2 - (void)swipe: (UISwipeGestureRecognizer *)sender
 3 {
 4     if (sender.direction == UISwipeGestureRecognizerDirectionLeft){
 5         if (self.isOpenLeft) return; //已经打开左滑,不再执行
 6         
 7         //开始左滑: 先调用block关闭其他可能左滑的cell
 8         if (self.closeOtherCellSwipe)
 9             self.closeOtherCellSwipe();
10         
11         [UIView animateWithDuration:0.5 animations:^{
12             sender.view.center = CGPointMake(0, CELLHEIGHT * 0.5);
13         }];
14         self.isOpenLeft = YES;
15     }
16     else if (sender.direction == UISwipeGestureRecognizerDirectionRight){
17         [self closeLeftSwipe]; //关闭左滑
18     }
19 }
20 
21 //关闭左滑,恢复原状
22 - (void)closeLeftSwipe{
23     if (!self.isOpenLeft) return; //还未打开左滑,不需要执行右滑
24     
25     [UIView animateWithDuration:0.5 animations:^{
26         self.containerView.center = CGPointMake(SCREENWIDTH * 0.5, CELLHEIGHT * 0.5);
27     }];
28     self.isOpenLeft = NO;
29 }

控制器部分代码:

 1 #pragma mark - 代理方法
 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
 3     return self.dataArr.count;
 4 }
 5 
 6 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 7     TanTableViewCell *cell = [TanTableViewCell cellWithTableView:tableView];
 8     
 9     MemberModel *model = [self.dataArr objectAtIndex:indexPath.row];
10     [cell setData:model]; //设置数据
11     
12     __weak typeof(self) tempSelf = self;
13     __weak typeof(cell) tempCell = cell;
14     
15     //设置删除cell回调block
16     cell.deleteMember = ^{
17         NSIndexPath *tempIndex = [tempSelf.tablView indexPathForCell:tempCell];
18         [tempSelf.dataArr removeObject:tempCell.model];
19         [tempSelf.tablView deleteRowsAtIndexPaths:@[tempIndex] withRowAnimation:UITableViewRowAnimationLeft];
20     };
21     
22     //设置当cell左滑时,关闭其他cell的左滑
23     cell.closeOtherCellSwipe = ^{
24         for (TanTableViewCell *item in tempSelf.tablView.visibleCells) {
25             if (item != tempCell) [item closeLeftSwipe];
26         }
27     };
28     
29     return cell;
30 }

DEMO下载:

github地址:https://github.com/xiaotanit/Tan_UITableViewCellLeftSwipe

csdn地址:http://download.csdn.net/detail/tandaxia/9479428

原文链接:http://www.cnblogs.com/tandaxia/p/5346659.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Charlie's Road

Container ViewController自定义转场控制器。

最近接触到新公司的老项目改版。自从来了之后一直在忙另一个项目,也没有看老项目的实现逻辑。 看到设计稿的时候,并不是普通的树形标签导航的样子。大致效果如FaceU...

1261
来自专栏full stack development

iOS的异步绘制--YYAsyncLayer源码分析

最近看了YYAsyncLayer在这里总结一下。YYAsyncLayer是整个YYKit异步渲染的基础。整个项目的Github地址在这里。你可以先下载了一睹为快...

6100
来自专栏程序员互动联盟

【Windows编程】系列第六篇:创建Toolbar与Statusbar

上一篇我们学习了解了如何使用Windows GDI画图,该应用程序都是光光的静态窗口,我们使用Windows应用程序,但凡稍微复杂一点的程序都会有工具栏和状态栏...

4703
来自专栏华仔的技术笔记

提升UITableView性能-复杂页面的优化

3015
来自专栏xx_Cc的学习总结专栏

iOS中用application 来管理电池栏状态

2127
来自专栏mukekeheart的iOS之旅

iOS学习——tableview中带编辑功能的cell键盘弹出遮挡和收起问题解决

  最近在项目中经常用到UITableView中的cell中带有UITextField或UITextView的情况,然后在这种场景下,当我们点击屏幕较下方的ce...

6948
来自专栏君赏技术博客

如果免费使用Reveal一些心得

之前用的一位大神破解的Reveal1.6.3版本,后来发现出现了很多的免费版本。也不敢用新的一直使用1.6.3的破解版本。

1563
来自专栏DannyHoo的专栏

MJRefreshFooter明杰刷新控件结束加载显示“没有更多内容”

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

2501
来自专栏陈满iOS

iOS开发验证:取消UITableView的Footer自带的悬停效果

对于继承UITableViewController,如果想更改tableview样式,请重写初始化方法:

6512
来自专栏技术总结

MJRefresh源码剖析与学习

建议查看原文:https://www.jianshu.com/p/23c876f8ae39(不定时更新)

2014

扫码关注云+社区

领取腾讯云代金券