开发经常用到cell侧滑的功能,iOS8之前需要我们自定义,因为iOS8之前的侧滑,只能显示一个按钮。在iOS8之后苹果公司推出了新的API,UITableViewRowAction类,可以添加多个功能。
// 必须写的方法(否则iOS 8无法删除,iOS 9及其以上不写没问题),和editActionsForRowAtIndexPath配对使用,里面什么不写也行
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
}
// 添加自定义的侧滑功能
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
// 添加一个删除按钮
UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
// 先移除数据源数据
[self.dataArray removeObjectAtIndex:indexPath.row];
// 再动态刷新UITableView
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
NSLog(@"删除按钮");
}];
UITableViewRowAction *topRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"置顶" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"置顶按钮");
}];
/// 设置按钮颜色,Normal默认是灰色的,Default默认是红色的
topRowAction.backgroundColor = [UIColor orangeColor];
UITableViewRowAction *cancelRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"取消关注" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"取消关注按钮");
}];
return @[deleteRowAction,topRowAction,cancelRowAction];
}
但是需求有时候就是想要侧滑带有图片的效果,苹果的UITableViewRowAction 是不带图片的。
先看效果图:
8442F82F-3466-433F-ADC1-1AACF098352C.png
我自定义的思路: 给cell添加滑动手势,根据手势来移动cell.contentView.frame来移动位置。在gestureRecognizerShouldBegin判断是否开启了侧滑,开始后,在cell的底部添加一个试图,用来放删除,等按钮的superview。这样就达到了侧滑的效果。
给每一个cell添加一个滑动的手势UIPanGestureRecognizer,
- (void)panAction:(UIPanGestureRecognizer *)panRecognizer {
CGPoint point = [panRecognizer translationInView:panRecognizer.view];
UIGestureRecognizerState state = panRecognizer.state;
[panRecognizer setTranslation:CGPointZero inView:panRecognizer.view];
if (state == UIGestureRecognizerStateChanged) {
CGRect frame = self.contentView.frame;
frame.origin.x += point.x;
if (frame.origin.x > 15) {
frame.origin.x = 15;
} else if (frame.origin.x < -30 -(sideslipsBtnW*self.count)) {
frame.origin.x = -30 -(sideslipsBtnW*self.count);
}
self.contentView.frame = frame;
} else if (state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [panRecognizer velocityInView:panRecognizer.view];
if (self.contentView.frame.origin.x == 0) {
return;
} else if (self.contentView.frame.origin.x > 5) {
[self hiddenWithBounceAnimation];
} else if (fabs(self.contentView.frame.origin.x) >= 40 && velocity.x <= 0) {
[self showSideslip];
} else {
[self hiddenSideslip];
}
} else if (state == UIGestureRecognizerStateCancelled) {
[self hiddenAllSideslip];
}
}
在cell添加手势你会发现你的tableView滚动不了。因为与TableView手势冲突了,回YES即可同时执行多种手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([otherGestureRecognizer.view isKindOfClass:[UITableView class]]) {
return YES;
}
return NO;
}
在代理里面判断是否要触发侧滑,当cell滑动的角度大于45°,则不触发侧滑。如果侧滑出现后,你不要滑动TableView的话,将上面的gestureRecognizer注释。
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == _panRecognizer) {
if (!self.tableView.scrollEnabled) {
[self hiddenAllSideslip];
return NO;
}
UIPanGestureRecognizer *gesture = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint translation = [gesture translationInView:gesture.view];
// 如果手势相对于水平方向的角度大于45°, 则不触发侧滑
BOOL shouldBegin = fabs(translation.y) <= fabs(translation.x);
if (!shouldBegin) return NO;
shouldBegin = YES;
if (shouldBegin) {
if (self.rightBtnImageArray.count == 0) return NO;
// 添加侧滑试图。
[self setActions:self.rightBtnImageArray];
}
return shouldBegin;
}else if (gestureRecognizer == _tableViewPan) {
if (self.tableView.scrollEnabled) {
return NO;
}
}
return YES;
}
通过self.tableView.visibleCells获取到cell列表关闭侧滑。
- (void)hiddenAllSideslip {
for (NHReceiveTableViewCell *cell in self.tableView.visibleCells) {
if ([cell isKindOfClass:NHReceiveTableViewCell.class]) {
[cell hiddenSideslip];
}
}
}
网友评论