iOS 自定义UITabView左滑样式及滑动背景

216 阅读2分钟

1.自定义左滑样式

单个左滑按钮的情况下可以使用图片转color的方式设置UITableViewRowAction的背景色:

-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view setNeedsLayout];
}

/**自定义设置iOS11系统下的左滑删除按钮大小*/
//开始编辑左滑删除
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    self.deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
                                                                               title:nil
                                                                             handler:^(UIContextualAction *action, UIView *sourceView, void (^completionHandler)(BOOL)) {
        // 删除逻辑
          
        completionHandler(YES);
    }];
    
    CGRect rect = CGRectZero;
    CGFloat scale = 0.0f;
    for (UIView *view in self.tableView.subviews) {
        NSLog(@"view:%@", view);
        if ([view isKindOfClass:NSClassFromString(@"_UITableViewCellSwipeContainerView")]) {
            for (UIView *subView in view.subviews) {
                if ([subView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                    for (UIView *actionView in subView.subviews) {
                        if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                            rect = actionView.frame;
                            if (rect.size.height > 0) {
                                scale = rect.size.width / rect.size.height;
                            }
                            
                        }
                    }
                }
            }
        }
    }
    
    if (CGRectEqualToRect(rect, CGRectZero)) {
        rect = [self.tableView rectForRowAtIndexPath:indexPath];
        rect.size.width = 74;
    }
    
    VVLog(@"trailingSwipeActionsConfigurationForRowAtIndexPath:%@", NSStringFromCGRect(rect));
       
    self.deleteAction.backgroundColor = [UIColor colorWithPatternImage:[self setBackImageView:rect]];
    
    UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[self.deleteAction]];
    config.performsFirstActionWithFullSwipe = YES; // 控制是否允许全幅滑动执行动作

    return config;
}

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    UIView *targetView;
    
    for (UIView *view in self.tableView.subviews) {
        if (@available(iOS 13.0, *)) {
            if ([view isKindOfClass:NSClassFromString(@"_UITableViewCellSwipeContainerView")]) {
                for (UIView *subView in view.subviews) {
                    if ([subView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                        for (UIView *actionView in subView.subviews) {
                            if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                                targetView = actionView;
                            }
                        }
                    }
                }
            }
        } else {
            if ([view isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                for (UIView *actionView in view.subviews) {
                    if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                        targetView = actionView;
                    }
                }
            }
        }
        
    }
    
    if (targetView) {
//        targetView.backgroundColor = RGBA(237, 237, 240, 1);
        self.deleteAction.backgroundColor = [UIColor colorWithPatternImage:[self setBackImageView:targetView.bounds]];
        NSLog(@"viewWillLayoutSubviews -- targetView.bounds:%@", NSStringFromCGRect(targetView.bounds));
    } else {
        NSLog(@"viewWillLayoutSubviews -- targetView:%@", NSStringFromCGRect(targetView.bounds));
    }
}

//自定义视图
-(UIImage *)setBackImageView:(CGRect)rect {
    // 自定义视图
    UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, rect.size.height)];
    customView.backgroundColor = RGBA(237, 237, 240, 1);
    CGFloat height = rect.size.height-20;
    CGFloat width = rect.size.width;
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    label.text = @"删除";
    label.textColor = [UIColor whiteColor];
    label.backgroundColor = [UIColor redColor];
    label.font = [UIFont systemFontOfSize:16];
    label.textAlignment = NSTextAlignmentCenter;
    [customView addSubview:label];
    VVLog(@"setBackImageView:%@", NSStringFromCGRect(label.frame));
    return [UIView imageWithView:customView];
}

view的扩展方法

@implementation UIView (Extention)
//View转Image
//使用该方法不会模糊,根据屏幕密度计算
+ (UIImage *)convertViewToImage:(UIView *)view {
    
    UIImage *imageRet = [[UIImage alloc]init];
    //UIGraphicsBeginImageContextWithOptions(区域大小, 是否是非透明的, 屏幕密度);
    UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, [UIScreen mainScreen].scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    imageRet = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return imageRet;
    
}
@end

2.查找UISwipeActionPullView

step1.在tableview的代理方法willBeginEditingRowAtIndexPath里调用

这一步必须进行,否则当前控制器的viewWillLayoutSubviews不会执行

-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view setNeedsLayout];
}
step2.重写viewWillLayoutSubviews方法,查找到UISwipeActionPullView
-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    UIView *targetView;
    
    for (UIView *view in self.tableView.subviews) {
        if (@available(iOS 13.0, *)) {
            if ([view isKindOfClass:NSClassFromString(@"_UITableViewCellSwipeContainerView")]) {
                for (UIView *subView in view.subviews) {
                    if ([subView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                        for (UIView *actionView in subView.subviews) {
                            if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                                targetView = actionView;
                            }
                        }
                    }
                }
            }
        } else {
            if ([view isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                for (UIView *actionView in view.subviews) {
                    if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                        targetView = actionView;
                    }
                }
            }
        }
        
    }
    
    if (targetView) {
//        targetView.backgroundColor = RGBA(237, 237, 240, 1);
        self.deleteAction.backgroundColor = [UIColor colorWithPatternImage:[self setBackImageView:targetView.bounds]];
        NSLog(@"viewWillLayoutSubviews -- targetView.bounds:%@", NSStringFromCGRect(targetView.bounds));
    } else {
        NSLog(@"viewWillLayoutSubviews -- targetView:%@", NSStringFromCGRect(targetView.bounds));
    }
}