今天愚人节,小伙们,愚人节快乐!
实现一个小功能,滑动菜单,显示隐藏的功能菜单, 先上图:
这里尝试用了下使用三个方式来实现了这个功能:
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