最近有需求需要用到自定義刪除按鈕樣式的UITableViewCell铁蹈。剛開始采用了修改系統(tǒng)刪除按鈕樣式的方法项棠,效果還可以》可是在iOS11上,由于UITableViewCell刪除按鈕實現(xiàn)形式的改變妻坝,這個方法就失效了伸眶,而一些第三方庫實現(xiàn)起來既復(fù)雜又有限制,因此就寫了個簡單版的刽宪,僅供參考厘贼。
方式一
思路
找到UITableViewCell的刪除頁面,重寫頁面上的刪除按鈕樣式
方法
- 重寫UITableViewCell的
- (void)layoutSubviews;
方法圣拄,通過遍歷subViews的方式找到刪除按鈕所在的頁面UITableViewCellDeleteConfirmationView - 通過遍歷subViews的方式在UITableViewCellDeleteConfirmationView上找到刪除按鈕并移除
- 在UITableViewCellDeleteConfirmationView上添加自定義樣式的刪除按鈕和點擊事件
- 通過控制代理方法
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
中返回空格的個數(shù)來決定刪除按鈕的寬度 - 需要實現(xiàn)代理方法
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
嘴秸,就算沒有具體內(nèi)容也可以
優(yōu)點
由于只是修改了樣式,因此相關(guān)的交互效果與系統(tǒng)的一致
局限性
刪除按鈕的樣式有一定的局限性庇谆,并且在iOS11上岳掐,UITableViewCell刪除按鈕的實現(xiàn)形式從根本上有了改變,該方法失效
方式二
思路
自定義UITableViewCell
方法
- 為了盡量與系統(tǒng)的交互效果保持一致(即滑動刪除)饭耳,自定義UITableViewCell的主體控件是UIScrollView
- 所有其它的控件串述,包括自定義的刪除按鈕都是添加在這個scrollView上的
- 為了滑動后有足夠的空間顯示刪除按鈕,將scrollView的contentSize設(shè)置為
CGSizeMake(ScreenWidth + deleteBtnWidth + margin, CellHeight)
- 刪除按鈕的處理方式有兩種:
- 添加在屏幕之外寞肖,固定在scrollView上纲酗,會隨著scrollView的滑動而逐漸顯示在屏幕上
- 添加在屏幕之內(nèi)衰腌,被另一個頁面遮蓋住。遮蓋它的頁面固定在scrollView上觅赊,會隨著scrollView的滑動逐漸移開右蕊;而它在scrollView內(nèi)的位置會隨著scrollView的滑動而不斷改變,使其在屏幕上的位置保持不變
- 為了與系統(tǒng)效果更相近茉兰,選擇了方式二尤泽,具體代碼如下:
_deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom] ;
_deleteBtn.frame = CGRectMake(ScreenWidth - deleteBtnWidth - margin, 7.5, deleteBtnWidth, CellHeight - 15) ;
[_deleteBtn addTarget:self action:@selector(deleteCell) forControlEvents:UIControlEventTouchUpInside] ;
[_scrollView addSubview:_deleteBtn] ;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if(scrollView.contentOffset.x > 0) {
_deleteBtn.frame = CGRectMake(scrollView.contentOffset.x + ScreenWidth - deleteBtnWidth - margin, 7.5, deleteBtnWidth, CellHeight - 15) ;
}
else {
_deleteBtn.frame = CGRectMake(ScreenWidth - deleteBtnWidth - margin, 7.5, deleteBtnWidth, CellHeight - 15) ;
}
}
注意
- 由于scrollView會吸收觸摸事件,為了讓tableViewCell能夠接收到觸摸事件规脸,需要重寫scrollView的相關(guān)方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesMoved:touches withEvent:event];
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesEnded:touches withEvent:event];
[super touchesEnded:touches withEvent:event];
}
- 在顯示刪除按鈕的情況下點擊tableViewCell需隱藏刪除按鈕:
- (void)clickWithCompletion:(void(^)(void))completion {
if(_scrollView.contentOffset.x > 0) {
//滑動過程中禁止scrollView的交互坯约,防止重復(fù)點擊引起的卡頓效果
_scrollView.userInteractionEnabled = NO ;
[UIView animateWithDuration:0.3 animations:^{
[_scrollView setContentOffset:CGPointZero] ;
} completion:^(BOOL finished) {
_scrollView.userInteractionEnabled = YES ;
}] ;
}
else {
completion () ;
}
}
- 由于UITableViewCell的重用機制,如果某一行cell左滑顯示了刪除按鈕莫鸭,在此情況下滑動tableView闹丐,那么將會在其它行出現(xiàn)顯示刪除按鈕的cell。為了解決該問題被因,需要創(chuàng)建一個對象來記錄每個cell刪除按鈕的顯示情況
優(yōu)點
刪除按鈕的樣式能夠完全自定義卿拴,不受系統(tǒng)的限制
局限性
交互效果與系統(tǒng)的相比有所差異
demo
具體的實現(xiàn)代碼見:https://github.com/bbbxxxbx/-