自定义 UITableView 的 Cell 删除样式
一、需求
先说下我们的需求,在一个 tableView 中,左滑删除某个 cell 时,需要展示如下图所示的样式,浅灰色
底色,橘红色
文字。
1、修改删除按钮的文字
修改删除按钮的文字很简单,只需要实现下面的方法:
//修改编辑按钮文字
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return @"Delete";
}
2、修改删除按钮的背景颜色和文字颜色
首先我按照常规的在 editActionsForRowAtIndexPath
方法中处理:
- (NSArray*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
// delete action
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
}];
deleteAction.backgroundColor = [UIColor colorWithHexString:Color_F7F7F7];
return @[deleteAction];
}
但发现只能通过 deleteAction.backgroundColor
改变背景颜色,却无法改变字体颜色。
而系统提供的几种 UITableViewRowActionStyle
也不符合我的需求:
typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
UITableViewRowActionStyleDefault = 0,
UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
UITableViewRowActionStyleNormal
}
默认 UITableViewRowActionStyleDefault
的样子:
UITableViewRowActionStyleNormal
的样子:
二、解决办法
解决办法有我从网上找来的,最新的 iOS12 的则是我自己试验出来的。解决办法也会随着 iOS 系统的升级而发生变化,因为系统控件的结构可能会发生变化,导致遍历不出要找到的视图。
1、系统版本 < iOS 11 的处理方式
iOS11 以前的处理方式是遍历 Cell 的 subViews 子视图找到 UITableViewCellDeleteConfirmationView
,只需在 Cell 的 .m 文件中添加 layoutSubviews
代码:
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subView in self.subviews) {
if ([NSStringFromClass([subView class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
UIButton *bgView = (UIButton *)[subView.subviews firstObject];
bgView.backgroundColor = [UIColor colorWithHexString:Color_F0F0F0];
[bgView setTitleColor:[UIColor colorWithHexString:Color_MainColor] forState:UIControlStateNormal];
}
}
}
2、iOS 11 <= 系统版本 < iOS 13 的处理方式
这个系统版本需要在 tableView 中添加 layoutSubviews
,我是写了一个 tableView 的父类,在父类的 .m 中添加了 layoutSubviews
。同时我还在 tableView 的 .h 中声明一个 cellHeightRef 来修改删除 Button 的高度。
- 简单来说就是在 tableView 的 subviews 中遍历出
UISwipeActionPullView
,再从UISwipeActionPullView
中遍历出UISwipeActionStandardButton
。再修改 button 的样式即可。
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
//修改背景颜色
subview.backgroundColor = [UIColor clearColor];
//修改按钮-颜色
UIButton *swipeActionStandardBtn = subview.subviews[0];
if ([swipeActionStandardBtn isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
CGFloat swipeActionStandardBtnOX = swipeActionStandardBtn.frame.origin.x;
CGFloat swipeActionStandardBtnW = swipeActionStandardBtn.frame.size.width;
swipeActionStandardBtn.frame = CGRectMake(swipeActionStandardBtnOX, 0, swipeActionStandardBtnW, self.cellHeightRef - 10);
[swipeActionStandardBtn setTitleColor:[UIColor colorWithHexString:Color_MainColor] forState:UIControlStateNormal];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
}
}
}
}
3、系统版本 == iOS 13 的处理方式(大于 13 的还未知,等出了新的我再更新)
iOS 13 中和上面的 iOS 13 之前的方法几乎一样,只不过是 tableView 内部的父子视图关系发生了变化, UISwipeActionStandardButton
位置变了。即原来把 subView 改为了 subview.subviews.firstObject,才能得到 UISwipeActionStandardButton
。
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([subview.subviews.firstObject isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
//修改背景颜色
subview.subviews.firstObject.backgroundColor = [UIColor clearColor];
//修改按钮-颜色
UIButton *swipeActionStandardBtn = subview.subviews.firstObject.subviews[0];
if ([swipeActionStandardBtn isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
CGFloat swipeActionStandardBtnOX = swipeActionStandardBtn.frame.origin.x;
CGFloat swipeActionStandardBtnW = swipeActionStandardBtn.frame.size.width;
swipeActionStandardBtn.frame = CGRectMake(swipeActionStandardBtnOX, 0, swipeActionStandardBtnW, self.cellHeightRef - 10);
[swipeActionStandardBtn setTitleColor:[UIColor colorWithHexString:Color_MainColor] forState:UIControlStateNormal];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
}
}
}
}