寫在開頭:本文所介紹的方法使用的是iOS8-10中的API盐肃,不過同樣支持在iOS11上運(yùn)行骡显。
<最近更新時(shí)間:2017-09-11>
目錄:
- 效果展示
- 系統(tǒng)默認(rèn)左滑菜單實(shí)現(xiàn)
- 自定義多個(gè)左滑菜單選項(xiàng)
- 自定義左滑菜單選項(xiàng)圖標(biāo)
4.1 實(shí)現(xiàn)方法 (支持iOS8-10, 11)
4.2 實(shí)現(xiàn)原理:UITableView視圖層級(jí)(iOS8-10, 11) - TableCell上有其他按鈕的處理方法
1. 效果展示
本文介紹兩種UITableView左滑菜單的實(shí)現(xiàn)方法米酬,效果如下:
系統(tǒng)默認(rèn)效果
自定義圖標(biāo)效果 (類似“郵件”應(yīng)用)
2. 系統(tǒng)默認(rèn)左滑菜單實(shí)現(xiàn)
如果只需要使用默認(rèn)圖標(biāo)飞盆,只需要在對(duì)應(yīng)的TableViewController里實(shí)現(xiàn)數(shù)據(jù)源方法tableView:commitEditingStyle:forRowAtIndexPath就行了:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self removeAction:indexPath.section]; // 在此處自定義刪除行為
}
else
{
DEBUG_OUT(@"Unhandled editing style: %ld", (long) editingStyle);
}
}
向左滑動(dòng)table cell析命,該cell會(huì)自動(dòng)進(jìn)入編輯模式(cell.isEditing = 1)备典,并在右邊出現(xiàn)刪除按鈕喜每,紅底白字务唐,按鈕上的文字會(huì)根據(jù)系統(tǒng)語言自動(dòng)改變雳攘;點(diǎn)擊該按鈕則觸發(fā)commitEditingStyle執(zhí)行相應(yīng)的動(dòng)作。
如果不進(jìn)行自定義,默認(rèn)的左滑菜單只會(huì)有一個(gè)按鈕,不過按鈕上的文字可以用隨意進(jìn)行更改系馆,按鈕的寬度會(huì)根據(jù)文字標(biāo)題長(zhǎng)度自動(dòng)調(diào)整,需要自己支持多語言:
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"想寫什么都行";
}
效果如下:PS:如果除了文字內(nèi)容外喧兄,還想調(diào)整其它,比如文字顏色啊楚,背景顏色吠冤,選項(xiàng)的寬高等,則可以拿到對(duì)應(yīng)的UIButton以后直接修改恭理,具體方法參照本文2) b部分拯辙。
3. 自定義多個(gè)左滑菜單選項(xiàng)
如果需要超過一個(gè)左滑選項(xiàng),需要實(shí)現(xiàn)代理方法tableView:editActionsForRowAtIndexPath颜价,在里面創(chuàng)建多個(gè)UITableViewRowAction:
- (NSArray*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
// delete action
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:NSLocalizedString(@"DeleteLabel", @"") handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
[tableView setEditing:NO animated:YES]; // 這句很重要涯保,退出編輯模式,隱藏左滑菜單
[self removeNotificationAction:index];
}];
// read action
// 根據(jù)cell當(dāng)前的狀態(tài)改變選項(xiàng)文字
NSInteger index = indexPath.section;
BOOL isRead = [[NotificationManager instance] read:index];
NSString *readTitle = isRead ? @"Unread" : @"Read";
// 創(chuàng)建action
UITableViewRowAction *readAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:readTitle handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
[tableView setEditing:NO animated:YES]; // 這句很重要周伦,退出編輯模式夕春,隱藏左滑菜單
[[NotificationManager instance] setRead:!isRead index:index];
}];
return @[deleteAction, readAction];
}
可以看到這里我們創(chuàng)建了delete和read兩個(gè)action。這是因?yàn)閷?shí)現(xiàn)了該方法以后专挪,1) 中用的commitEditingStyle:forRowAtIndexPath就不會(huì)被觸發(fā)了及志,所以刪除按鈕也需要自己定義。
[tableView setEditing:NO animated:YES]; 這一行代碼很重要寨腔,它的效果是在點(diǎn)擊之后退出編輯模式速侈,關(guān)閉左滑菜單。如果忘了加這一句的話迫卢,即使點(diǎn)擊了按鈕cell也不會(huì)還原锌畸。在1) 中使用默認(rèn)模式的時(shí)候,系統(tǒng)會(huì)自動(dòng)幫我們調(diào)用這一句靖避,現(xiàn)在則需要手動(dòng)調(diào)用。
對(duì)創(chuàng)建并返回的每個(gè)action比默,apple library會(huì)自動(dòng)幫我們生成一個(gè)對(duì)應(yīng)按鈕幻捏,配置好基本的交互,并添加到左滑菜單中命咐。
上圖我們對(duì)兩個(gè)action都指定了UITableViewRowActionStyleNormal(灰底白字)篡九,不過其實(shí)有幾種不同的預(yù)設(shè)外觀 (不要問我為啥有兩個(gè)都是紅底白字。醋奠。榛臼。)
? UITableViewRowActionStyleNormal:灰底白字
? UITableViewRowActionStyleDefault:紅底白字
? UITableViewRowActionStyleDestructive:紅底白字
我們還可以更改action button的背景色伊佃,在創(chuàng)建action的時(shí)候添加一行代碼即可:
deleteAction.backgroundColor = [UIColor orangeColor];
readAction.backgroundColor = [UIColor blueColor];
效果如下:4. 自定義左滑菜單選項(xiàng)外觀
自定義左滑選項(xiàng)外觀的資料很少,我做的時(shí)候找得相當(dāng)辛苦沛善。不過后來理解了UITableView的視圖層級(jí)航揉,一切就變得很簡(jiǎn)單了。先放實(shí)現(xiàn)方法金刁,再放原理解釋帅涂。
4.1 實(shí)現(xiàn)方法 (支持iOS8-10, 11)
為了同時(shí)支持iOS8-10和iOS11, 我把操作選項(xiàng)外觀的代碼統(tǒng)一放在UITableView的ViewController的- (void)viewDidLayoutSubviews實(shí)現(xiàn)。
這樣做的原因有兩個(gè):
- 原本因?yàn)閕OS8-10中尤蛮,左滑選項(xiàng)是UITableViewCell的子視圖媳友,而在iOS11中,左滑選項(xiàng)變成了UITableView的子視圖产捞。雖然可以用tabelCell.superview來獲取tableView醇锚,不過我認(rèn)為最好從高層級(jí)去操作低層級(jí)。所以統(tǒng)一在UITableView層處理坯临。
- iOS8-10的UITableViewCellDeleteConfirmationView子視圖出現(xiàn)得較晚焊唬。在代理方法willBeginEditingRowAtIndexPath中還沒有出現(xiàn),而在viewDidLayoutSubviews則可以保證子視圖出現(xiàn)尿扯。
首先我們遍歷UITableView的子視圖拿到選項(xiàng)按鈕(UIButton)的reference求晶,對(duì)iOS8-10和iOS11做不同處理:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) NSIndexPath* editingIndexPath; //當(dāng)前左滑cell的index,在代理方法中設(shè)置
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (self.editingIndexPath)
{
[self configSwipeButtons];
}
}
Xcode 8 編譯版本:(如果你使用的是Xcode 9衷笋,參見下面)
- (void)configSwipeButtons
{
// 獲取選項(xiàng)按鈕的reference
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0"))
{
// iOS 11層級(jí) (Xcode 8編譯): UITableView -> UITableViewWrapperView -> UISwipeActionPullView
for (UIView *subview in self.tableView.subviews)
{
if ([subview isKindOfClass:NSClassFromString(@"UITableViewWrapperView")])
{
for (UIView *subsubview in subview.subviews)
{
if ([subsubview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")] && [subsubview.subviews count] >= 2)
{
// 和iOS 10的按鈕順序相反
UIButton *deleteButton = subsubview.subviews[1];
UIButton *readButton = subsubview.subviews[0];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}
}
}
}
}
else
{
// iOS 8-10層級(jí): UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView
NotificationCell *tableCell = [self.tableView cellForRowAtIndexPath:self.editingIndexPath];
for (UIView *subview in tableCell.subviews)
{
if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 2)
{
UIButton *deleteButton = subview.subviews[0];
UIButton *readButton = subview.subviews[1];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
[subview setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]];
}
}
}
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}
Xcode 9 編譯版本:(比Xcode 8編譯出來少一層)
- (void)configSwipeButtons
{
// 獲取選項(xiàng)按鈕的reference
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0"))
{
// iOS 11層級(jí) (Xcode 9編譯): UITableView -> UISwipeActionPullView
for (UIView *subview in self.tableView.subviews)
{
if ([subview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")] && [subview.subviews count] >= 2)
{
// 和iOS 10的按鈕順序相反
UIButton *deleteButton = subsubview.subviews[1];
UIButton *readButton = subsubview.subviews[0];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}
}
}
else
{
// iOS 8-10層級(jí): UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView
NotificationCell *tableCell = [self.tableView cellForRowAtIndexPath:self.editingIndexPath];
for (UIView *subview in tableCell.subviews)
{
if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 2)
{
UIButton *deleteButton = subview.subviews[0];
UIButton *readButton = subview.subviews[1];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
[subview setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]];
}
}
}
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}
注意一下這里我們用到了一個(gè)變量self.editingIndexPath芳杏,這代表著當(dāng)前左滑的cell的index,方便我們獲取iOS8-10上面的tableCell的reference辟宗。分別在控制進(jìn)入和退出編輯模式的代理方法中設(shè)置的:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
self.editingIndexPath = indexPath;
[self.view setNeedsLayout]; // 觸發(fā)-(void)viewDidLayoutSubviews
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
self.editingIndexPath = nil;
}
[self.view setNeedsLayout]; 這一句非常重要爵赵,它的作用強(qiáng)制UITableView重新繪圖。只有添加了這一句泊脐,- (void)viewDidLayoutSubviews才會(huì)被調(diào)用空幻,才能使我們的自定義外觀生效。
好了容客,我們已經(jīng)拿到了按鈕(UIButton)的reference秕铛,然后就可以給按鈕添加了圖片,并且設(shè)置文本的字體和顏色了缩挑。
- (void)configDeleteButton:(UIButton*)deleteButton
{
if (deleteButton)
{
[deleteButton.titleLabel setFont:[UIFont fontWithName:@"SFUIText-Regular" size:12.0]];
[deleteButton setTitleColor:[[ColorUtil instance] colorWithHexString:@"D0021B"] forState:UIControlStateNormal];
[deleteButton setImage:[UIImage imageNamed:@"Delete_icon_.png"] forState:UIControlStateNormal];
[deleteButton setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]];
// 調(diào)整按鈕上圖片和文字的相對(duì)位置(該方法的實(shí)現(xiàn)在下面)
[self centerImageAndTextOnButton:deleteButton];
}
}
- (void)configReadButton:(UIButton*)readButton
{
if (readButton)
{
[readButton.titleLabel setFont:[UIFont fontWithName:@"SFUIText-Regular" size:12.0]];
[readButton setTitleColor:[[ColorUtil instance] colorWithHexString:@"4A90E2"] forState:UIControlStateNormal];
// 根據(jù)當(dāng)前狀態(tài)選擇不同圖片
BOOL isRead = [[NotificationManager instance] read:self.editingIndexPath.row];
UIImage *readButtonImage = [UIImage imageNamed: isRead ? @"Mark_as_unread_icon_.png" : @"Mark_as_read_icon_.png"];
[readButton setImage:readButtonImage forState:UIControlStateNormal];
[readButton setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]];
// 調(diào)整按鈕上圖片和文字的相對(duì)位置(該方法的實(shí)現(xiàn)在下面)
[self centerImageAndTextOnButton:readButton];
}
}
如果沒有[self centerImageAndTextOnButton:readButton]但两,則效果如下:可以看到圖標(biāo)在左,文字在右供置,還互相重合谨湘。這就是我們熟悉的UIButton的外觀處理,需要分別修改UILabel和UIImageView的frame:
- (void)centerImageAndTextOnButton:(UIButton*)button
{
// this is to center the image and text on button.
// the space between the image and text
CGFloat spacing = 35.0;
// lower the text and push it left so it appears centered below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
// increase the content height to avoid clipping
CGFloat edgeOffset = (titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);
// move whole button down, apple placed the button too high in iOS 10
if (SYSTEM_VERSION_LESS_THAN(@"11.0"))
{
CGRect btnFrame = button.frame;
btnFrame.origin.y = 18;
button.frame = btnFrame;
}
}
調(diào)整過后就可以做到文章開頭展示的效果了:PS:假如僅支持iOS8-10的話,我個(gè)人是傾向于創(chuàng)建一個(gè)custom class紧阔,繼承UITableViewCell坊罢,然后在該custom class中-(void)layoutSubviews來實(shí)現(xiàn)的。那樣代碼更干凈擅耽,不需要特意去調(diào)用[self.view setNeedsLayout]; 不過為了支持新版本總是要有所犧牲的活孩。
4.2 實(shí)現(xiàn)原理:UITableView視圖層級(jí)(iOS8-10, 11)
不想看原理可以跳過這部分。
和iOS8-10相比秫筏,iOS11的左滑選項(xiàng)的視圖層級(jí)有了較大改變诱鞠。最顯著的改變是從是UITableViewCell的子視圖變成了UITableView的子視圖≌饩矗總結(jié)一下就是:
iOS 8-10: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton
iOS 11 (Xcode 8編譯): UITableView -> UITableViewWrapperView -> UISwipeActionPullView -> UISwipeActionStandardButton
iOS 11 (Xcode 9編譯): UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton
--
iOS8-10下的層級(jí):
在tableView代理方法里設(shè)置斷點(diǎn)打印發(fā)現(xiàn)航夺,正常狀態(tài)下cell上只有兩個(gè)subview:
(lldb) po [tableCell subviews]
<__NSArrayM 0x14de75670>(
<UITableViewCellContentView: 0x14dd56940; frame = (0 0; 440 105); opaque = NO; gestureRecognizers = <NSArray: 0x14dd65ff0>; layer = <CALayer: 0x14dd56ac0>>,
<_UITableViewCellSeparatorView: 0x14dd73810; frame = (15 154.5; 347 0.5); layer = <CALayer: 0x14dd736f0>>
)
而在左滑進(jìn)入editing mode之后,就變成了3個(gè)崔涂,多出來一個(gè) 叫做UITableViewCellDeleteConfirmationView的子視圖:
(lldb) po [tableCell subviews]
<__NSArrayM 0x14de75670>(
<UITableViewCellDeleteConfirmationView: 0x14de737d0; frame = (375 0; 0 105); clipsToBounds = YES; autoresize = H; animations = { bounds.origin=<CASpringAnimation: 0x14db56aa0>; bounds.size=<CASpringAnimation: 0x14db5b2e0>; position=<CASpringAnimation: 0x14db498e0>; bounds.origin-2=<CASpringAnimation: 0x14db8a3d0>; bounds.size-2=<CASpringAnimation: 0x14db26c10>; }; layer = <CALayer: 0x14de72fc0>>,
<UITableViewCellContentView: 0x14dd56940; frame = (0 0; 375 105); opaque = NO; gestureRecognizers = <NSArray: 0x14dd65ff0>; layer = <CALayer: 0x14dd56ac0>>,
<_UITableViewCellSeparatorView: 0x14dd73810; frame = (15 154.5; 347 0.5); layer = <CALayer: 0x14dd736f0>>
)
再進(jìn)一步查看這個(gè)多出來的UITableViewCellDeleteConfirmationView的子視圖阳掐,發(fā)現(xiàn)兩個(gè)UIButton:
(lldb) po tableCell.subviews[0].subviews
<__NSArrayM 0x14dea14c0>(
<_UITableViewCellActionButton: 0x14de93ea0; frame = (71.5 0; 80.5 105); opaque = NO; autoresize = H; layer = <CALayer: 0x14de93150>>,
<_UITableViewCellActionButton: 0x14de9d900; frame = (0 0; 71.5 105); opaque = NO; autoresize = H; layer = <CALayer: 0x14de9dbb0>>
)
最后再打印一下這兩個(gè)UIButton的title,發(fā)現(xiàn)分別是“Read”和“Delete”冷蚂。
也就是說缭保,這兩個(gè)UIButton,分別對(duì)應(yīng)我們?cè)赼部分創(chuàng)建的兩個(gè)UITableViewRowAction蝙茶。所以我們只要遍歷UITableViewCell的子視圖艺骂,拿到對(duì)應(yīng)UIButton的reference,什么修改高度隆夯,添加圖片钳恕,修改字體,都是手到擒來蹄衷。
--
iOS11下的層級(jí) (用Xcode 8編譯)
依然在tableView代理方法里設(shè)置斷點(diǎn)打印發(fā)現(xiàn)忧额,UITableViewCell下面沒有UITableViewCellDeleteConfirmationView子視圖了,不過在UITableViewWrapperView下面愧口,多了一個(gè)UISwipeActionPullView睦番。
(lldb) po self.tableView.subviews
<__NSArrayM 0x1c0652cf0>(
<UITableViewWrapperView: 0x105094200; frame = (0 0; 1000 1000); gestureRecognizers = <NSArray: 0x1c4457e50>; layer = <CALayer: 0x1c4224de0>; contentOffset: {0, 0}; contentSize: {1000, 1000}; adjustedContentInset: {0, 0, 0, 0}>,
<UIImageView: 0x10466bb20; frame = (994.5 733; 2.5 220); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x1c0426900>>
)
(lldb) po [self.tableView.subviews[0] subviews]
<__NSArrayM 0x1c04457f0>(
<UITableViewCell: 0x10e17d800; baseClass = UITableViewCell; frame = (0 277.5; 375 212.5); autoresize = W; layer = <CALayer: 0x1c0427c80>>,
<: UITableViewCell: 0x10e165200; baseClass = UITableViewCell; frame = (0 8; 375 261.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x1c0423300>>,
<UISwipeActionPullView: 0x10de126a0; cellEdge = UIRectEdgeRight, actions = <NSArray: 0x1c44430c0>>
)
再看一下這個(gè)UISwipeActionPullView子視圖,發(fā)現(xiàn)了我們要找的選項(xiàng)按鈕:
(lldb) po subview2.subviews
<__NSArrayM 0x1c0452ba0>(
<UISwipeActionStandardButton: 0x14deae190; frame = (0 0; 591 104.5); opaque = NO; autoresize = W+H; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x1c0435860>>,
<UISwipeActionStandardButton: 0x14debd7c0; frame = (0 0; 591 104.5); opaque = NO; autoresize = W+H; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x1c0621200>>
)
這兩個(gè)button的title和action都和我們之前所創(chuàng)建的左滑選項(xiàng)相對(duì)應(yīng)耍属,所以我們可以用類似的方法遍歷UITableView的子視圖托嚣,拿到對(duì)應(yīng)UIButton的reference進(jìn)行修改。
--
iOS11下的層級(jí) (用Xcode 9編譯)
Xcode 9 默認(rèn)使用iOS11 SDK來編譯厚骗,添加打印后發(fā)現(xiàn)Xcode 9 編譯出來的沒有UITableViewWrapperView這一層注益,UISwipeActionPullView的子視圖直接附屬于UITableViewCell。
除了少了一層UITableViewWrapperView以外溯捆,其他和Xcode 8編譯出來的一樣。
放一下Xcode 8、9編譯的對(duì)比圖:
xcode8.png
|
xcode9.png
|
---|
5. TableCell上有其它按鈕的處理方法
我自己做的時(shí)候遇到了一種特殊情況提揍,UITableViewCell上面帶有比較顯著的button啤月,類似下圖的這種情況:這種情況比較尷尬的就是當(dāng)你左滑的時(shí)候如果剛好碰到了YES或者NO button, 在進(jìn)入左滑選項(xiàng)的同時(shí)會(huì)觸發(fā)按鈕選項(xiàng),相當(dāng)容易引發(fā)誤操作劳跃。為了解決這個(gè)問題谎仲,我在TableViewController中實(shí)現(xiàn)了下面兩個(gè)代理方法:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableCell = [tableView cellForRowAtIndexPath:indexPath];
// disable button touch event during swipe
for (UIView *view in [tableCell.contentView subviews])
{
if ([view isKindOfClass:[UIButton class]]) {
[view setUserInteractionEnabled:NO];
}
}
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableCell = [tableView cellForRowAtIndexPath:indexPath];
for (UIView *view in [tableCell.contentView subviews])
{
if ([view isKindOfClass:[UIButton class]]) {
[view setUserInteractionEnabled:YES];
}
}
}
tableView:willBeginEditingRowAtIndexPath是在cell進(jìn)入editing mode之前調(diào)用的,在這里將contentView下面的所有按鈕的交互設(shè)置為disabled刨仑。
tableView:didEndEditingRowAtIndexPath是在cell即將退出editing mode時(shí)調(diào)用的郑诺,在這里將之前被disable的所有button的交互重新設(shè)置為enabled。
這樣就可以保證在左滑菜單出現(xiàn)的時(shí)候杉武,原本cell上的那些按鈕都處于不能點(diǎn)按的狀態(tài)辙诞,也就不會(huì)觸發(fā)誤操作了。
PS: 試過直接disable 整個(gè)contentView不起作用轻抱,必須直接disable對(duì)應(yīng)的UIButton才行飞涂,推測(cè)跟apple自己處理event的有限次序有關(guān)。