自定義 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,self.cellHeightRef - 10);
[swipeActionStandardBtn setTitleColor:[UIColor colorWithHexString:Color_MainColor] forState:UIControlStateNormal];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[swipeActionStandardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
}
}
}
}
複製程式碼