iOS自定義UITableView實(shí)現(xiàn)不同系統(tǒng)下的左滑刪除功能詳解
前言
在我們的app開發(fā)當(dāng)中,經(jīng)常會(huì)用到UITableView 的左滑刪除的功能,通常的話效果如下
但有時(shí)候系統(tǒng)現(xiàn)有的功能并不能完全滿足我們的開發(fā)需求,這樣就需要我們?cè)谄洮F(xiàn)有的功能基礎(chǔ)上自定義我們所需要的功能了。下圖是在項(xiàng)目中自定義的按鈕(只是修改了按鈕的frame而已)。
然后我就總結(jié)了一下根據(jù)不同的需求自定義不同的按鈕。
一、系統(tǒng)默認(rèn)左滑刪除按鈕
如果你對(duì)左滑刪除按鈕的要求不高,僅僅只是實(shí)現(xiàn)UITableView上cell的左滑刪除功能,那在UITableView的代理方法中添加以下兩種方法便可實(shí)現(xiàn)需求:
//使用系統(tǒng)默認(rèn)的刪除按鈕 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete){ } } //自定義系統(tǒng)默認(rèn)的刪除按鈕文字 - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { return @"自定義按鈕”; }
效果如下所示:
系統(tǒng)自帶
雖然這樣能基本實(shí)現(xiàn)功能,但是我們發(fā)現(xiàn)右邊的按鈕和左邊的黃色區(qū)域的高度并不一樣。這是因?yàn)橛疫叞粹o是和UITableViewCell的高度一致,而左邊的黃色區(qū)域只是一張圖片而已,其高度設(shè)置和UITableViewCell的高度并不一致,才會(huì)導(dǎo)致這樣的布局出現(xiàn)。如果我們想要?jiǎng)h除按鈕和左邊圖片一樣的高度,那我們就需要自定義刪除按鈕的高度了。
二、自定義左滑刪除按鈕
如果我們想要實(shí)現(xiàn)不止一個(gè)自定義按鈕的功能,那我們就需要在UITableView代理方法- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {}
中添加我們所需要的多個(gè)按鈕了。如下是在不同的cell上添加一個(gè)或兩個(gè)左滑按鈕:
//自定義多個(gè)左滑菜單選項(xiàng) - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewRowAction *deleteAction; deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"刪除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [tableView setEditing:NO animated:YES];//退出編輯模式,隱藏左滑菜單 }]; if (indexPath.row == 1) {//在不同的cell上添加不同的按鈕 UITableViewRowAction *shareAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"分享" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [tableView setEditing:NO animated:YES];//退出編輯模式,隱藏左滑菜單 }]; shareAction.backgroundColor = [UIColor blueColor]; return @[deleteAction,shareAction]; } return @[deleteAction]; }
在上述代理方法中我們就可以實(shí)現(xiàn)在cell中添加一個(gè)或多個(gè)左滑按鈕了,根據(jù)點(diǎn)擊不同的按鈕實(shí)現(xiàn)不同的響應(yīng)方法便可。其中[tableView setEditing:NO animated:YES];
方法可以在點(diǎn)擊按鈕之后退出編輯模式并隱藏左滑菜單。但如果我們想要修改按鈕的其他屬性如標(biāo)題、背景顏色怎么辦?點(diǎn)擊進(jìn)入U(xiǎn)ITableViewRowAction類中,我們會(huì)發(fā)現(xiàn)以下屬性和方法:
@interface UITableViewRowAction : NSObject <NSCopying> + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler; @property (nonatomic, readonly) UITableViewRowActionStyle style; @property (nonatomic, copy, nullable) NSString *title; @property (nonatomic, copy, nullable) UIColor *backgroundColor; // default background color is dependent on style @property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect; @end
其中 @property (nonatomic, readonly) UITableViewRowActionStyle style;
是指設(shè)置所添加按鈕父視圖的背景顏色以及按鈕字體顏色:
typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) { UITableViewRowActionStyleDefault = 0,//紅底白字 UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault, UITableViewRowActionStyleNormal//灰底白字 } NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
而@property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;
提供了一個(gè)背景模糊效果,有興趣的可以自行研究一下。
上述的方法和屬性只能滿足我們的部分需求,如果我們想要改變按鈕的大小或者設(shè)置帶圖片的按鈕怎么辦?那就需要我們?cè)谝晥D中找到我們所要修改的按鈕,并設(shè)置它的各種屬性。由于在iOS8-10和iOS11下自定義按鈕處在不同的視圖層次中,所以需要我們先了解UITableView上的視圖層次。下圖為對(duì)比:
左iOS10/右iOS11(Xcode9中)
從對(duì)比圖中可以看出:
(1).iOS10下視圖層次為:UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton,我們所需自定義的按鈕視圖UITableViewCellDeleteConfirmationView(左圖中紅框處)是UITableViewCell的子視圖。
(2).iOS11下視圖層次為:在Xcode 8中編譯為: UITableView -> UITableViewWrapperView -> UISwipeActionPullView -> UISwipeActionStandardButton;
在Xcode 9中編譯為: UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton。(iOS11中用Xcode 8和Xcode 9中編譯有略微的差別),我們所需自定義的按鈕視圖UISwipeActionPullView(右圖中紅框處)是UITableView的子視圖。
由于不同系統(tǒng)下的視圖層次不一樣,因此我們?cè)陧?xiàng)目中需要根據(jù)不同的代碼去同時(shí)適配iOS8-10和iOS11。
在iOS8-10中( 以下均在Xcode 9中編譯):
在該系統(tǒng)下由于我們所需自定義的按鈕視圖UITableViewCellDeleteConfirmationView是UITableViewCell的子視圖,所以我們?cè)谧远xUITableViewCell子類中遍歷它的subviews即可。代碼如下:
- (void)layoutSubviews { /**自定義設(shè)置iOS8-10系統(tǒng)下的左滑刪除按鈕大小*/ for (UIView * subView in self.subviews) { if ([subView isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) { subView.backgroundColor = [UIColor clearColor];//去掉默認(rèn)紅色背景 //設(shè)置按鈕frame CGRect cRect = subView.frame; cRect.origin.y = self.contentView.frame.origin.y + 10; cRect.size.height = self.contentView.frame.size.height - 20; subView.frame = cRect; //自定義按鈕的文字大小 if (subView.subviews.count == 1 && self.indexPath.section == 0) {//表示有一個(gè)按鈕 UIButton * deleteButton = subView.subviews[0]; deleteButton.titleLabel.font = [UIFont systemFontOfSize:20]; } //自定義按鈕的圖片 if (subView.subviews.count == 1 && self.indexPath.section == 1) {//表示有一個(gè)按鈕 UIButton * deleteButton = subView.subviews[0]; [deleteButton setImage:[UIImage imageNamed:@"login_btn_message"] forState:UIControlStateNormal]; [deleteButton setTitle:@"" forState:UIControlStateNormal]; } //自定義按鈕的文字圖片 if (subView.subviews.count >= 2 && self.indexPath.section == 0) {//表示有兩個(gè)按鈕 UIButton * deleteButton = subView.subviews[1]; UIButton * shareButton = subView.subviews[0]; [deleteButton setTitle:@"" forState:UIControlStateNormal]; [shareButton setTitle:@"" forState:UIControlStateNormal]; [self setUpDeleteButton:deleteButton]; [self setUpShareButton:shareButton]; } } } }
在iOS11中:
在該系統(tǒng)下由于我們所需自定義的按鈕視圖UISwipeActionPullView是UITableView的子視圖,所以我們可以在控制器中自定義UITableView子類中遍歷它的subviews即可(以下方法是寫在UITableView的代理方法- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
中的,該代理方法每次會(huì)在開始左滑按鈕前調(diào)用)。代碼如下:
/**自定義設(shè)置iOS11系統(tǒng)下的左滑刪除按鈕大小*/ //開始編輯左滑刪除 - (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger section = indexPath.section; if (@available(iOS 11.0, *)) { for (UIView * subView in self.customTableView.subviews) { if ([subView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) { subView.backgroundColor = [UIColor clearColor];//如果自定義只有一個(gè)按鈕就要去掉按鈕默認(rèn)紅色背景 //設(shè)置按鈕frame for (UIView * sonView in subView.subviews) { if ([sonView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) { CGRect cRect = sonView.frame; cRect.origin.y = sonView.frame.origin.y + 10; cRect.size.height = sonView.frame.size.height - 20; sonView.frame = cRect; } } //自定義按鈕的文字大小 if (subView.subviews.count == 1 && section == 0) {//表示有一個(gè)按鈕 UIButton * deleteButton = subView.subviews[0]; deleteButton.titleLabel.font = [UIFont systemFontOfSize:20]; } //自定義按鈕的圖片 if (subView.subviews.count == 1 && section == 1) {//表示有一個(gè)按鈕 UIButton * deleteButton = subView.subviews[0]; [deleteButton setImage:[UIImage imageNamed:@"login_btn_message"] forState:UIControlStateNormal];; } //自定義按鈕的文字圖片 if (subView.subviews.count >= 2 && section == 0) {//表示有兩個(gè)按鈕 UIButton * deleteButton = subView.subviews[1]; UIButton * shareButton = subView.subviews[0]; [self setUpDeleteButton:deleteButton]; [self setUpShareButton:shareButton]; } } } } }
如果我們想在左滑刪除結(jié)束后實(shí)現(xiàn)一些功能,我們可以在UITableView中實(shí)現(xiàn)以下代理方法:
//結(jié)束編輯左滑刪除 - (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath { } 如果我們想分別設(shè)置UITableViewCell是否需要實(shí)現(xiàn)左滑功能,可以在下面代理方法中實(shí)現(xiàn): //判斷是否顯示左滑刪除 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; }
在不同系統(tǒng)下分別添加以上代碼即可實(shí)現(xiàn)我們所需要的自定義左滑刪除按鈕,效果圖如下:
以上是我總結(jié)整理的在不同系統(tǒng)下的自定義UITableView左滑刪除功能。
如有不足之處,歡迎指正交流,Demo地址:左滑刪除 (本地下載)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- iOS開發(fā)TableView網(wǎng)絡(luò)請(qǐng)求及展示預(yù)加載實(shí)現(xiàn)示例
- ios開發(fā)UITableViewCell圖片加載優(yōu)化詳解
- iOS ScrollView嵌套tableView聯(lián)動(dòng)滾動(dòng)的思路與最佳實(shí)踐
- iOS優(yōu)化UITableViewCell高度計(jì)算的一些事兒
- iOS11解決UITableView側(cè)滑刪除無限拉伸的方法
- ios UITableView 自定義右滑刪除的實(shí)現(xiàn)代碼
- iOS開發(fā)學(xué)習(xí)TableView展現(xiàn)一個(gè)list實(shí)例
相關(guān)文章
如何為Xcode添加刪除整行、復(fù)制整行及在下方新建一行快捷鍵詳解
xcode是蘋果公司向開發(fā)人員提供的集成開發(fā)環(huán)境,開發(fā)者們經(jīng)常會(huì)使用到,下面這篇文章主要給大家介紹了關(guān)于如何為Xcode添加刪除整行、復(fù)制整行及在下方新建一行快捷鍵的相關(guān)資料,需要的朋友可以參考下。2018-04-04詳解iOS應(yīng)用使用Storyboard布局時(shí)的IBOutlet與IBAction
這篇文章主要介紹了iOS應(yīng)用使用Storyboard布局時(shí)的IBOutlet與IBAction,文中還附帶講解了為什么IBOutlet屬性是weak的,需要的朋友可以參考下2016-04-04iOS實(shí)現(xiàn)自定義表單實(shí)例代碼
表單對(duì)大家來說應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于iOS如何實(shí)現(xiàn)自定義表單的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問題詳解
這篇文章主要給大家介紹了關(guān)于iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07使用iOS控件UICollectionView生成可拖動(dòng)的桌面的實(shí)例
本篇文章主要介紹了使用iOS控件UICollectionView生成可拖動(dòng)的桌面,具有一定的參考價(jià)值,有需要的可以了解一下。2016-12-12iOS如何獲取設(shè)備型號(hào)的最新方法總結(jié)
在開發(fā)中,我們經(jīng)常需要獲取設(shè)備的型號(hào)以進(jìn)行數(shù)據(jù)統(tǒng)計(jì)或者做不同的適配。這篇文章主要給大家介紹了關(guān)于iOS如何獲取設(shè)備型號(hào)的最新方法,需要的朋友可以參考下2018-11-11IOS實(shí)現(xiàn)微信朋友圈相冊(cè)評(píng)論界面的翻轉(zhuǎn)過渡動(dòng)畫
現(xiàn)在很多人幾乎每天都離不開微信,大家有沒有發(fā)現(xiàn)在點(diǎn)開微信相冊(cè)的時(shí)候,想要在相冊(cè)圖片界面跳轉(zhuǎn)查看點(diǎn)贊和評(píng)論時(shí),微信會(huì)采用界面翻轉(zhuǎn)的過渡動(dòng)畫來跳轉(zhuǎn)到評(píng)論界面,點(diǎn)擊完成又會(huì)翻轉(zhuǎn)回到圖片界面,這不同于一般的導(dǎo)航界面滑動(dòng)動(dòng)畫,于是學(xué)著做了一下,有需要一起看看。2016-08-08iOS實(shí)現(xiàn)左右可滑動(dòng)的選擇條實(shí)例代碼分享
本文通過實(shí)例代碼給大家介紹了ios實(shí)現(xiàn)左右可滑動(dòng)的選擇條功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-03-03