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

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

                     

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

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

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

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

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

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

部分代码:

1、使用UISwipeGestureRecognizer  +  Delegate

自定义UITableViewCell部分代码:

 //
// TanTableViewCell.h
// Tan_SwipeTableViewCell
//
// Created by PX_Mac on 16/3/25.
// Copyright © 2016年 PX_Mac. All rights reserved.
// #import <UIKit/UIKit.h>
@class MemberModel;
@class TanTableViewCell; @protocol TanTableViewCellDelegate <NSObject> @optional
- (void)deleteMember: (TanTableViewCell *)cell; //协议方法:删除会员
- (void)closeOtherCellLeftSwipe; //关闭其他单元格的左滑 @end @interface TanTableViewCell : UITableViewCell //静态构造方法
+ (instancetype)cellWithTableView: (UITableView *)tableView; @property (nonatomic, strong) MemberModel *model; //模型属性
@property (nonatomic, weak) id<TanTableViewCellDelegate> delegate; //代理 - (void)setData: (MemberModel *)model; //设置要显示的数据
- (void)closeSwipe; //关闭滑动,恢复原样(用于在滑动当前单元格时,把其他已经左滑的单元格关闭) @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(, 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部分代码:

 //初始化子控件
- (void)initSubControls{
/* ...... */ //3、给容器containerView绑定拖动手势
UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.containerView addGestureRecognizer:panGes];
self.panGes = panGes; self.selectionStyle = UITableViewCellSelectionStyleNone; //设置单元格选中样式
[self.contentView bringSubviewToFront:self.containerView]; //设置containerView显示在最上层
} //拖动手势(拖拽手势和UITableView的下拉刷新手势有冲突,造成下拉刷新不能使用)
- (void)pan: (UIPanGestureRecognizer *)sender
{
//动画结束时修正位置
if (sender.state == UIGestureRecognizerStateEnded){ //关闭其他cell的左拖拽
if ([self.delegate respondsToSelector:@selector(closeOtherCellLeftPan:)])
[self.delegate closeOtherCellLeftPan: self]; if (sender.view.frame.origin.x < -SCREENWIDTH * 0.25){
sender.view.transform = CGAffineTransformMakeTranslation(-SCREENWIDTH * 0.5, );
[sender setTranslation:CGPointZero inView:sender.view]; //必须归0
}
else{
[self closeLeftPan];
}
} CGPoint point = [sender translationInView:self.contentView]; CGFloat tx = sender.view.transform.tx; if (tx < - SCREENWIDTH * 0.5 || tx > ) return; //形变
sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, );
[sender setTranslation:CGPointZero inView:sender.view]; //必须归0
} //关闭左拖拽
- (void)closeLeftPan{
self.panGes.view.transform = CGAffineTransformMakeTranslation(, );
[self.panGes setTranslation:CGPointZero inView:self.panGes.view]; //必须归0
}

3、UISwipeGestureRecognizer + block

自定义UITableViewCell部分代码:

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

控制器部分代码:

 #pragma mark - 代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArr.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TanTableViewCell *cell = [TanTableViewCell cellWithTableView:tableView]; MemberModel *model = [self.dataArr objectAtIndex:indexPath.row];
[cell setData:model]; //设置数据 __weak typeof(self) tempSelf = self;
__weak typeof(cell) tempCell = cell; //设置删除cell回调block
cell.deleteMember = ^{
NSIndexPath *tempIndex = [tempSelf.tablView indexPathForCell:tempCell];
[tempSelf.dataArr removeObject:tempCell.model];
[tempSelf.tablView deleteRowsAtIndexPaths:@[tempIndex] withRowAnimation:UITableViewRowAnimationLeft];
}; //设置当cell左滑时,关闭其他cell的左滑
cell.closeOtherCellSwipe = ^{
for (TanTableViewCell *item in tempSelf.tablView.visibleCells) {
if (item != tempCell) [item closeLeftSwipe];
}
}; return cell;
}

DEMO下载:

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

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

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

自定义UITableViewCell实现左滑动多菜单功能LeftSwipe的更多相关文章

  1. 自定义uitableviewcell通过加上滑动手势进行删除对应的行。PS:用代理来实现

    #import <UIKit/UIKit.h> @class ZSDCustomCell; //协议 @protocol ZSDCustomCellDelegate <NSObjec ...

  2. IOS uitableviewcell 向左滑动删除编辑等

    主要实现这个方法就好了 -(NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActions ...

  3. Android自定义组件——四个方向滑动的菜单实现

    今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下. 一.效果演示 (说明:目前没有安装Android模拟器,制作的动态图片太卡了,就贴一下静 ...

  4. Android自定义组件系列【15】——四个方向滑动的菜单实现

    今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下. 一.效果演示 (说明:目前没有安装Android模拟器,制作的动态图片太卡了,就贴一下静 ...

  5. 使用Java语言开发微信公众平台(八)——自定义菜单功能

    随着上一篇文章的结束,我们已经实现了所有消息的类型的回复功能.今天,我们来学习更加高大上,也更加重要的自定义菜单功能. 一.了解自定义菜单 自定义菜单是微信公众平台最常用也是最重要的功能之一.根据微信 ...

  6. 仿EXCEL插件,智表ZCELL产品V1.7 版本发布,增加自定义右键菜单功能

    详细请移步 智表(ZCELL)官网www.zcell.net 更新说明  这次更新主要应用户要求,主要解决了自定义右键菜单事件的支持,并新增了公式中自定义函数传参.快捷键剪切等功能,欢迎大家体验使用. ...

  7. iOS之UITableView带滑动操作菜单的Cell

    制作一个可以滑动操作的 Table View Cell 本文翻译自 http://www.raywenderlich.com/62435/make-swipeable-table-view-cell- ...

  8. iOS之UI--使用SWRevealViewController实现侧边菜单功能详解实例

    使用SWRevealViewController实现侧边菜单功能详解 下面通过两种方法详解SWRevealViewController实现侧边菜单功能: 1.使用StoryBoard实现   2.纯代 ...

  9. iOS之UI--使用SWRevealViewController 实现侧边菜单功能详解实例

     iOS之UI--使用SWRevealViewController 实现侧边菜单功能详解实例 使用SWRevealViewController实现侧边菜单功能详解 下面通过两种方法详解SWReveal ...

随机推荐

  1. .NET跨平台之旅:将示例站点升级至 .NET Core 1.1 Preview 1

    今天微软发布了 .NET Core 1.1 Preview 1(详见 Announcing .NET Core 1.1 Preview 1 ),紧跟 .NET Core 前进的步伐,我们将示例站点 h ...

  2. Web 前端攻防(2014版)

    在百度 FEX 团队时写的.有次让我写点前端开发中注意的安全规范,结果写着写着就跑题了,写了一堆纯前端实现的攻击方式...当然还有防范措施. 文章就懒得粘过来了~ 直接贴个地址算了:) http:// ...

  3. ASP.NET Aries 4.0 开源发布:已完成基础功能优化重写

    主要更新: 1:增加AR.Global.GetUser() 方法返回当前登陆者的用户信息. 2:重写AR.Combobox 支持下拉树. 3:调整及扩展Input下拉的配置参数. 4:优化及新增AR. ...

  4. 值得收藏!国外最佳互联网安全博客TOP 30

    如果你是网络安全从业人员,其中重要的工作便是了解安全行业的最新资讯以及技术趋势,那么浏览各大安全博客网站或许是信息来源最好的方法之一.最近有国外网站对50多个互联网安全博客做了相关排名,小编整理其中排 ...

  5. 冗余代码都走开——前端模块打包利器 Rollup.js 入门

    之前翻译过一篇文章,介绍了通过 ES2015 的解构赋值语法引入模块,可以让打包工具(browserify)最终编译出来的代码量最小化. 殊不知在 webpack 1.X 版本是无法利用该特性来避免引 ...

  6. SQL Server 索引和表体系结构(聚集索引)

    聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在各个网站上面也有很多关于这方面写的不错的文章,我写这篇文章的目的也是为了将所有的知识点尽可能的组 ...

  7. 3D游戏中的画质与效率适配

      哪里来的需求? 众所周知,由于不同的设备配置不同.导致其CPU和GPU处理能力有高有低.同样的游戏想要在所有设备上运行流畅且画面精美,是不可能的.这就需要我们针对不同的设备能力进行画质调节,以保证 ...

  8. CSharpGL(26)在opengl中实现控件布局/渲染文字

    CSharpGL(26)在opengl中实现控件布局/渲染文字 效果图 如图所示,可以将文字.坐标轴固定在窗口的一角. 下载 CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入( ...

  9. 基于java的分布式爬虫

    分类 分布式网络爬虫包含多个爬虫,每个爬虫需要完成的任务和单个的爬行器类似,它们从互联网上下载网页,并把网页保存在本地的磁盘,从中抽取URL并沿着这些URL的指向继续爬行.由于并行爬行器需要分割下载任 ...

  10. 生成任意长度的随机数 JS

    1.Math.random().toString(36).substr(2); 结果:ywv6cnpkliahj4tep0 2.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...