iOS UITableView左滑操作功能的實(shí)現(xiàn)(iOS8-11)

該文同時(shí)發(fā)表在騰訊WeTest公眾號(hào):iOS UITableView左滑操作功能的實(shí)現(xiàn)(iOS8-11) 歡迎點(diǎn)擊閱讀

本文主要是介紹下iOS 11系統(tǒng)及iOS 11之前的系統(tǒng)在實(shí)現(xiàn)左滑操作功能上的區(qū)別,及如何自定義左滑的標(biāo)題顏色、字體

1似扔、左滑操作功能實(shí)現(xiàn)

1.1 如果左滑的時(shí)候只有一個(gè)操作按鈕懂扼,可以使用如下三個(gè)delegate方法來(lái)實(shí)現(xiàn):

//editing style
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleDelete;
}
//設(shè)置滑動(dòng)cell出現(xiàn)的button標(biāo)題揍移,默認(rèn)是"delete"
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
    return @"刪除";//or @"置頂"
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 //點(diǎn)擊按鈕后的操作
}

1.2 如果左滑有一個(gè)或多個(gè)操作按鈕绎秒,iOS8-10 可使用如下兩個(gè)delegate方法:

//如果tableView中的每一行都可以進(jìn)行左滑操作搔涝,該方法可不實(shí)現(xiàn)
//If not implemented, all editable cells will have UITableViewCellEditingStyleDelete
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == FMMineCollectionSection_AlbumItems) {
        return UITableViewCellEditingStyleDelete;
    }
    return UITableViewCellEditingStyleNone;
}

// 必須寫的方法(否則iOS 8無(wú)法刪除黍图,iOS 9及其以上不寫沒(méi)問(wèn)題)曾雕,和editActionsForRowAtIndexPath配對(duì)使用,里面什么不寫也行
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

}

//從iOS11開始該方法被廢棄
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewRowAction *topRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"置頂" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        //操作按鈕點(diǎn)擊的操作    
       }];
   topRowAction.backgroundColor = KE_COLOR(@"BT3");
   topRowAction.title = @"置頂";
  
    UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"刪除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
    NSLog(@"點(diǎn)擊了刪除");
}];
   return @[topRowAction, deleteRowAction];
  }
}

1.3 iOS 11之后助被,tableView的delegate增加了兩個(gè)方法剖张,用來(lái)取代editActionsForRowAtIndexPath方法,如下:

// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
// return nil to get the default swipe actions
- ( UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {

    UIContextualAction *topRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"置頂" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
    NSLog(@"點(diǎn)擊了置頂");
}];

    UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
    NSLog(@"點(diǎn)擊了刪除");
}];

    UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[topRowAction,deleteRowAction]];
    return config;
}

在1.2和1.3中揩环,如果是需要適配iOS 11之前的版本搔弄,以上三個(gè)方法都需要實(shí)現(xiàn)。

1.4 上面1.2和1.3中實(shí)現(xiàn)的方法的區(qū)別

體驗(yàn)上的不同就是當(dāng)左滑只有一個(gè)button時(shí)丰滑,iOS 11中可以一直左滑顾犹,滑到一定程度時(shí),會(huì)執(zhí)行點(diǎn)擊按鈕的操作褒墨,iOS 11之前的不會(huì)炫刷。

iOS 11之前如果想增大button區(qū)域,可通過(guò)在標(biāo)題前后加空格的方式貌亭,但iOS 11不行柬唯,加空格無(wú)效,button大小固定圃庭,超過(guò)4個(gè)字時(shí)換行顯示锄奢。

2圃郊、左滑操作自定義標(biāo)題顏色蔬咬、字體

因?yàn)橄到y(tǒng)對(duì)左滑出的按鈕只提供了3個(gè)可設(shè)置的屬性:title、backgroundColor甸怕、image书在,如果使用自定義的titleColor和font灰伟,就需要自己來(lái)實(shí)現(xiàn)了。實(shí)現(xiàn)的思想是hook系統(tǒng)實(shí)現(xiàn),但鑒于UITableView的view層級(jí)結(jié)構(gòu)在iOS 11中有所改變栏账,所以iOS8-10和iOS11的實(shí)現(xiàn)有所不同帖族,以下分別給出。

考慮到代碼的可復(fù)用性挡爵,自定義左滑操作的字體大小和顏色的代碼不寫在viewController中竖般,而是寫在UITableViewUITableViewCellCategory中,對(duì)外提供editActionTitleColoreditActionTitleFont屬性來(lái)設(shè)置顏色和大小茶鹃,需要使用自定義顏色和字體時(shí)只需要設(shè)置一下這兩個(gè)屬性即可涣雕。

2.1 iOS 8-10 設(shè)置標(biāo)題顏色和字體

左滑操作后,UITableView的層級(jí)結(jié)構(gòu)如下圖:

iOS8-10層級(jí)結(jié)構(gòu).png

由上圖可知闭翩,左滑的操作按鈕是在UITableViewCell的子view挣郭,所以我們可以在UITableViewCellcategory中hook掉layoutSubviews方法,找到UITableViewCellDeleteConfirmationView的子view button疗韵,設(shè)置字體顏色和大小兑障。

代碼如下:

- (void)applyEditActionButtonStyle
{
    if (self.editActionTitleColor) {//設(shè)置editActionTitleFont同理
        UIButton *btn = [self __findSwipActionButton];
        [btn setTitleColor:self.editActionTitleColor forState:UIControlStateNormal];
    }
}

- (UIButton *)__findSwipActionButton{
    if (![Common iOS11]) {
        UIView *extView = (UIView *)[self findSubviewOfTest:@"UITableViewCellDeleteConfirmationView" resursion:YES];
        for (UIButton *btn in extView.subviews) {
            if ([btn isKindOfClass:[UIButton class]]) {
             return btn;
            }
        }
    }
    return nil;
}

2.2 iOS 11 設(shè)置標(biāo)題顏色和字體

左滑操作后,UITableView的層級(jí)結(jié)構(gòu)如下圖:
iOS11 View的層級(jí)結(jié)構(gòu).png

由上圖可知伶棒,左滑的操作按鈕是在UITableView的子view旺垒,所以我們可以在UITableViewcategory中hook掉layoutSubviews方法,找到UISwipeActionPullView的子view button肤无,設(shè)置字體顏色和大小先蒋。

代碼如下:

- (void)applyEditActionButtonStyle
{
    if (self.editActionTitleColor) {//設(shè)置editActionTitleFont同理
        NSArray *btns = [self __findSwipActionButtons];
        for (UIButton *btn in btns) {
            [btn setTitleColor:self.editActionTitleColor forState:UIControlStateNormal];
        }
    }
}

- (NSArray<UIButton *> *)__findSwipActionButtons{
    if ([Common iOS11]) {
        NSMutableArray *buttons = [NSMutableArray array];
        for (UIView *extView in self.subviews) {
            if ([NSStringFromClass(extView.class) isEqualToString:@"UISwipeActionPullView"]) {
                for (UIButton *btn in extView.subviews) {
                    if ([btn isKindOfClass:[UIButton class]]) {
                        [buttons addObject:btn];//要返回所有的左滑出的button
                    }
                }
            }
        }
        return [buttons copy];
    }
    return nil;
}

3、遇到的問(wèn)題及原因分析

3.1 問(wèn)題是iOS 11上設(shè)置顏色有延遲宛渐,顏色有一個(gè)明顯的跳變竞漾,從系統(tǒng)默認(rèn)色跳轉(zhuǎn)到我設(shè)置的顏色

有問(wèn)題的代碼如下:

- (void)applyEditActionButtonStyle
{
    if (self.editActionTitleColor) {
        UIButton *btn = [self __findSwipActionButton];
        [btn setTitleColor:self.editActionTitleColor forState:UIControlStateNormal];
    }
}

- (UIButton *)__findSwipActionButton{
if ([Common iOS11]) {
    for (UIView *extView in self.subviews) {
        if ([NSStringFromClass(extView.class) isEqualToString:@"UISwipeActionPullView"]) {
            for (UIButton *btn in extView.subviews) {
                if ([btn isKindOfClass:[UIButton class]]) {
                        return btn;
                    }
                }
            }
        }
    }
    return nil;
}

3.2 問(wèn)題原因分析

當(dāng)左滑一個(gè)cell后,直接操作左滑另一個(gè)cell窥翩,這個(gè)時(shí)候tableView上會(huì)有兩個(gè)UISwipeActionPullView业岁,此時(shí)tableView的部分view層級(jí)如下圖所示:

two_swipeActionView.png

而上面的代碼,在__findSwipActionButton方法中寇蚊,找到其中一個(gè)UISwipeActionPullView上面的button就直接返回了笔时,沒(méi)有設(shè)置第二個(gè)UISwipeActionPullView的button的顏色,導(dǎo)致顯示了系統(tǒng)默認(rèn)色仗岸。

3.3 解決方法

將以上有問(wèn)題的代碼修改為以下代碼:找出所有的UISwipeActionPullView允耿,返回UISwipeActionPullView的button數(shù)組,對(duì)button數(shù)組進(jìn)行設(shè)置字體顏色和大小扒怖,這個(gè)數(shù)組最多有兩個(gè)元素较锡,因?yàn)樽蠡鱿乱粋€(gè)cell時(shí),上一個(gè)cell會(huì)逐漸消失盗痒,當(dāng)此cell左滑操作完成時(shí)蚂蕴,上一個(gè)左滑的cell也會(huì)完成消失。

解決后的代碼如2.2的示例代碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骡楼,一起剝皮案震驚了整個(gè)濱河市熔号,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸟整,老刑警劉巖跨嘉,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異吃嘿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)梦重,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門兑燥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人琴拧,你說(shuō)我怎么就攤上這事降瞳。” “怎么了蚓胸?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵挣饥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我沛膳,道長(zhǎng)扔枫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任锹安,我火速辦了婚禮短荐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叹哭。我一直安慰自己忍宋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布风罩。 她就那樣靜靜地躺著糠排,像睡著了一般。 火紅的嫁衣襯著肌膚如雪超升。 梳的紋絲不亂的頭發(fā)上入宦,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音廓俭,去河邊找鬼云石。 笑死,一個(gè)胖子當(dāng)著我的面吹牛研乒,可吹牛的內(nèi)容都是我干的汹忠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宽菜!你這毒婦竟也來(lái)了谣膳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铅乡,失蹤者是張志新(化名)和其女友劉穎继谚,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阵幸,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡花履,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挚赊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诡壁。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荠割,靈堂內(nèi)的尸體忽然破棺而出妹卿,到底是詐尸還是另有隱情,我是刑警寧澤蔑鹦,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布夺克,位于F島的核電站,受9級(jí)特大地震影響嚎朽,放射性物質(zhì)發(fā)生泄漏铺纽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一火鼻、第九天 我趴在偏房一處隱蔽的房頂上張望室囊。 院中可真熱鬧,春花似錦魁索、人聲如沸融撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)尝偎。三九已至,卻和暖如春鹏控,著一層夾襖步出監(jiān)牢的瞬間致扯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工当辐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抖僵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓缘揪,卻偏偏與公主長(zhǎng)得像耍群,于是被迫代替她去往敵國(guó)和親义桂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)蹈垢、插件慷吊、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 我一直相信書是有生命的。寫作的人把自己的氣息曹抬、思想溉瓶、神情融匯成一段段的話并編寫出的一個(gè)個(gè)的字后賜予了書靈魂。一篇文...
    千千千晚星閱讀 383評(píng)論 4 1
  • 我說(shuō)她幼稚,她卻覺(jué)得委屈 原創(chuàng)文 | 林子 (清風(fēng)浪港手寫鋪原創(chuàng)文张足,未經(jīng)授權(quán)請(qǐng)勿轉(zhuǎn)載) 三年前胞锰,我的閨蜜跟她男朋友...
    清風(fēng)浪港手寫鋪閱讀 220評(píng)論 0 0