在项目需求中,经常会有对 TableView Cell 左滑事件及按钮的自定义设置需求
iOS 11.0之前
左滑按钮
在iOS 11.0之前,我们可以看到 Cell 的左滑界面UITableViewCellDeleteConfirmationView
布局是在于 Cell 之中的,并且只有左滑事件之后才会添加到 Cell 中,在左滑界面中存在一个UIButton
的子视图,这便是我们需要自定义的视图
在自定义的 TableViewCell 中,重写
- (void)didTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state {
[super didTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
NSLog(@"%@", self.subviews);
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
subview.backgroundColor = [UIColor clearColor];
UIButton *btn = [subview.subviews objectAtIndex:0];
[btn setImage:[UIImage imageNamed:@"icon_delete"] forState:UIControlStateNormal];
[btn setTitle:nil forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor clearColor]];
}
}
}
}
左滑事件
在 tableView 的 delegate 方法中自带有 - (NSArray *)tableView:(UITableView*)tableView editActionsForRowAtIndexPath:(NSIndexPath*)indexPath
可自定义事件
- (UITableViewCellEditingStyle)tableView:(UITableView*)tableView editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewRowAction *rowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:nil handler:^(UITableViewRowAction *_Nonnullaction, NSIndexPath *_NonnullindexPath) {
[self showAlertWithIndexPath:indexPath];
}];
rowAction.backgroundColor = [UIColor cyanColor];
return @[rowAction];
}
至此iOS 11.0之前的版本的左滑自定义便已经可以了(当然,也可以自定义左滑时多个事件,原理也是一样的)
iOS 11.0之后
左滑按钮
在iOS 11.0之后的版本,左滑布局发生了改变
我们可以看到,此时也已经不是
UITableViewCellDeleteConfirmationView
,而是UISwipeActionPullView
,并且是UITableView
的子视图,因此,在 Cell 中重写- (void)didTransitionToState:(UITableViewCellStateMask)state
在iOS 11.0之后的系统并无作用。这是可以使用tableView的代理方法
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
if (@available(iOS 11.0, *)) {
[self customDeleteBtnAfteriOS11:tableView];
}
}
//在此方法中并不能有效的设置BGColor为clearColor
- (void)customDeleteBtnAfteriOS11:(UITableView *)tableView {
for (UIView *subview in tableView.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UISwipeActionPullView"]) {
// subview.backgroundColor = [UIColor clearColor];
UIButton *btn = [subview.subviews objectAtIndex:0];
[btn setImage:[UIImage imageNamed:@"icon_delete"] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
// [btn setBackgroundColor:[UIColor clearColor]];
}
}
}
左滑事件
iOS 11.0之后的当然能用之前的方法了,而苹果在11.0之后其实也新增了另外一个新的方法- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
,只在iOS 11.0之后的系统才有效,其实目前区别上也仅仅是action多了一个image属性,然而此image属性也不能显示原图,而是会被自动渲染。
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
if (@available(iOS 11.0, *)) {
WeakObj(self);
UIContextualAction *action = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"删除按钮"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
StrongObj(self);
[selfStrong showAlertWithIndexPath:indexPath];
completionHandler(YES);
}];
//action.image = [UIImage imageNamed:@"icon_delete"];//若仅设置此属性,会被系统渲染
action.backgroundColor = [UIColor cyanColor];
return [UISwipeActionsConfiguration configurationWithActions:@[action]];
}
return nil;
}
网友评论