UITableViewCell左滑显示按钮菜单
http://blog.jobbole.com/67272/
编辑模式下左滑可以显示DELETE按钮。如何可以自定义左滑显示的按钮呢?
整体思路
1.自定义UITableViewCell,并为其contentView添加左滑时希望显示的按钮。
2.在contentView上添加一个相同大小subView,作为正常情况下tableViewCell显示的内容。
3.为此subView添加pan事件,滑动的时候移动其位置,使按钮可以显示出来。
需要注意的问题
具体实现(仿微信效果)
新建自定义的TableViewCell
1.新建自定义的TableViewCell:DogTableViewCell。在storyboard中关联并添加左滑时希望显示的按钮。
2.在contentView上添加一个相同大小subView:containerView,作为正常情况下tableViewCell显示的内容。
3.设置containerView相对于其父view(contentView)的约束,并为其左右约束连接IBOutlet。左右滑动的时候需要修改这两个约束的值。
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *contentViewRightConstraint; @property (nonatomic, weak) IBOutlet NSLayoutConstraint *contentViewLeftConstraint;
左滑显示按钮
1.在awakeFromNib时添加UIPanGestureRecognizer。
self.panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panThisCell:)];
self.panRecognizer.delegate = self;
[self.containerView addGestureRecognizer:self.panRecognizer];
2.左滑动,移动containerView,显示按钮。
在UIGestureRecognizerStateBegan时,保存初始坐标:
self.panStartPoint = [recognizer translationInView:self.containerView]; self.startingRightLayoutConstraintConstant = self.contentViewRightConstraint.constant;
UIGestureRecognizerStateChanged时,根据新坐标判断是否左移。如果是的话,改变左右约束:
if (panningLeft){
CGFloat constant = MIN(-deltaX, [self buttonTotalWidth]);
self.contentViewRightConstraint.constant = constant;
self.contentViewLeftConstraint.constant = -self.contentViewRightConstraint.constant; //8
self.trackButton.hidden = NO;
self.deleteButton.hidden = NO;
}
在UIGestureRecognizerStateEnded时,根据移动的多少,判断要全部打开还是关闭,并用动画实现:
if (self.contentViewRightConstraint.constant >= halfOfButtonOne) {
[self setConstraintsToShowAllButtons:YES notifyDelegateDidOpen:YES];
} else {
[self resetConstraintContstantsToZero];
}
按钮显示时,点击任何位置隐藏按钮
1.增加UITapGestureRecognizer和UILongPressGestureRecognizer
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapThisCell)];
tap.delegate = self;
[self.containerView addGestureRecognizer:tap];
UILongPressGestureRecognizer *ltap = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(tapThisCell)];
ltap.delegate = self;
ltap.minimumPressDuration = 0.01;
ltap.enabled = YES;
[self.containerView addGestureRecognizer:ltap];
2.在gestureRecognizerShouldBegin中进行判断:
如果tableView是编辑模式(已显示按钮),并且收到的事件是点击手势(UILongPressGestureRecognizer),则隐藏按钮,并退出编辑模式。
如果没有在编辑模式,并且收到的是滑动手势,则响应手势。
其他情况下不响应手势。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if (self.tableView.editState == YES && self.panRecognizer != gestureRecognizer){
[self.tableView disableEdit];
return YES;
}
if (self.panRecognizer == gestureRecognizer && self.tableView.editState == NO){
return YES;
}
if (self.panRecognizer == gestureRecognizer && self.tableView.editCell != self){
return NO;
}
return NO;
}
tableView的上下滑动和tableViewCell的左滑动互斥
1.定义三种状态
#define ScrolStateNone 0//正常未滑动状态
#define ScrolStateDelete 1//左滑状态
#define ScrolStateScrol 2//上下滑动状态
2.UIGestureRecognizerStateChanged时,判断是上下滑还是左滑,并设置状态:
if (scrolState == ScrolStateNone){
if (abs(deltaX) < abs(deltaY)){
scrolState = ScrolStateScrol;
return;
}
else{
scrolState = ScrolStateDelete;
[self.tableView.tableView setScrollEnabled:NO];
}
}
如果在上下滑动状态,则不再处理UIGestureRecognizerStateChanged
if (scrolState == ScrolStateScrol){
return;
}
3.UIGestureRecognizerStateEnded时,如果为上下滑动状态,则还原为正常未滑动状态。
if (scrolState == ScrolStateScrol){
scrolState = ScrolStateNone;
return;
}
4.如果在滑动,则不响应其他手势。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
if (scrolState != ScrolStateNone)
return NO;
return YES;
}
浙公网安备 33010602011771号