0
点赞
收藏
分享

微信扫一扫

iOS Table View Cell 自定义左滑按钮及事件(系统自带方法)

在项目需求中,经常会有对 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;
}

Demo

GItHubDemo

本人第一次写此类文章,如有不足或者更好的方法,可以一起探讨,谢谢~
举报

相关推荐

0 条评论