// 以前的做法
// 1.ViewController代码如下:自定义三个左滑项
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *titleContent = @" ";
// 去电
UITableViewRowAction *callAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleContent handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
self.tableView.editing = NO;
[self callButtonTapped:@""];
}];
// 讯息
UITableViewRowAction *messageAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleContent handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
self.tableView.editing = NO;
[self messageButtonTapped];
}];
// SMS短讯
UITableViewRowAction *smsAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" " handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
self.tableView.editing = NO;
[self smsButtonTapped:@""];
}];
return @[smsAction, messageAction, callAction];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 进入编辑模式,适配iOS8
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
// 2.实现自定义左滑项的UI,主要是在Cell里面完成
- (void)layoutSubviews
{
[super layoutSubviews];
// 去掉隐式动画
[CATransaction begin];
[CATransaction setDisableActions:YES];
[self setupSlideBtn];
[CATransaction commit];
}
// 设置左滑菜单按钮的样式
- (void)setupSlideBtn
{
for (UIView *subView in self.subviews) {
if([subView isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
// SMS短讯
UIView *smsContentView = subView.subviews[0];
smsContentView.backgroundColor = ICAN_SLIDE_BTN_COLOR;
for (UIView *smsView in smsContentView.subviews) {
[smsView removeAllSubviews];
UIImageView *smsImage = [[UIImageView alloc] init];
smsImage.contentMode = UIViewContentModeScaleAspectFit;
smsImage.image = [UIImage imageNamed:@"sms_selected"];
CGFloat width = smsView.frame.size.width;
smsImage.frame = CGRectMake((width - 25) / 2, -15, 25, 25);
[smsView addSubview:smsImage];
// 文字
UILabel *sms = [UILabel labelWithFrame:CGRectMake((width - 60) / 2, smsImage.bottom, 60, 20) text:@"SMS短讯" textColor:ICAN_BLUE_THEME_COLOR font:ICAN_FONT(14)];
sms.textAlignment = NSTextAlignmentCenter;
[smsView addSubview:sms];
}
// 讯息
UIView *messageContentView = subView.subviews[1];
messageContentView.backgroundColor = ICAN_SLIDE_BTN_COLOR;
for (UIView *messageView in messageContentView.subviews) {
[messageView removeAllSubviews];
UIImageView *messageImage = [[UIImageView alloc] init];
messageImage.contentMode = UIViewContentModeScaleAspectFit;
messageImage.image = [UIImage imageNamed:@"message_selected"];
CGFloat width = messageView.frame.size.width;
messageImage.frame = CGRectMake((width - 25) / 2, -15, 25, 25);
[messageView addSubview:messageImage];
// 文字
UILabel *message = [UILabel labelWithFrame:CGRectMake((width - 35) / 2, messageImage.bottom, 35, 20) text:@"讯息" textColor:ICAN_BLUE_THEME_COLOR font:ICAN_FONT(14)];
message.textAlignment = NSTextAlignmentCenter;
[messageView addSubview:message];
}
// 去电
UIView *callContentView = subView.subviews[2];
//改背景颜色
callContentView.backgroundColor = ICAN_SLIDE_BTN_COLOR;
for (UIView *callView in callContentView.subviews) {
[callView removeAllSubviews];
UIImageView *callImage = [[UIImageView alloc] init];
callImage.contentMode = UIViewContentModeScaleAspectFit;
callImage.image = [UIImage imageNamed:@"phone_selected"];
CGFloat width = callView.frame.size.width;
callImage.frame = CGRectMake((width - 25) / 2, -15, 25, 25);
[callView addSubview:callImage];
// 文字
UILabel *call = [UILabel labelWithFrame:CGRectMake((width - 35) / 2, callImage.bottom, 35, 20) text:@"去电" textColor:ICAN_BLUE_THEME_COLOR font:ICAN_FONT(14)];
call.textAlignment = NSTextAlignmentCenter;
[callView addSubview:call];
}
}
}
效果图如下:
分割线========================================================================
以上方法是在iOS11以下有效,因为iOS11后UITableViewCell的层次结构发生了变化,它的子View中并不包含UITableViewCellDeleteConfirmationView这个控件了,所以要想实现替换左滑菜单的背景图片这种变态需求就需要另找办法了,解决方法如下:
// 这种方法是重写willTransitionToState这个方法,而不是重写layoutSubviews方法,因为在左滑菜单收起来的时候,背景图片会有闪一下的bug
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self setupSlideBtn];
});
}
// 设置左滑菜单按钮的样式
- (void)setupSlideBtn
{
// 判断系统是否是iOS11及以上版本
if (SYSTEM_VERSION_GREATER_THAN(@"11")) {
for (UIView *subView in self.superview.subviews) {
if (![NSStringFromClass([subView class]) isEqualToString:@"UISwipeActionPullView"]) {
continue;
}
for (UIView *buttonViews in subView.subviews) {
if (![NSStringFromClass([buttonViews class]) isEqualToString:@"UISwipeActionStandardButton"]) {
continue;
}
// 修改备注
UIView *remarkContentView = subView.subviews[0];
[self setupRowActionView:remarkContentView imageName:@"left_slide_modify_note2"];
// 删除
UIView *deleteContentView = subView.subviews[1];
[self setupRowActionView:deleteContentView imageName:@"left_slide_delete_button2"];
}
}
} else {
// iOS11以下做法
for (UIView *subView in self.subviews) {
if(![subView isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
continue;
}
// 删除
UIView *deleteContentView = subView.subviews[0];
[self setupRowActionView:deleteContentView imageName:@"left_slide_delete_button2"];
// 修改备注
UIView *remarkContentView = subView.subviews[1];
[self setupRowActionView:remarkContentView imageName:@"left_slide_modify_note2"];
}
}
}
// 设置背景图片
- (void)setupRowActionView:(UIView *)rowActionView imageName:(NSString *)imageName
{
rowActionView.backgroundColor = kViewBackgroundColor;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
[rowActionView insertSubview:imageView atIndex:0];
[imageView makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(rowActionView);
make.width.equalTo(80);
}];
}