自定義cell側(cè)滑刪除(仿別人的app)

將近一年半沒有寫blog了连锯,最近項目排期不是很緊,整理一下以前遇到的問題,之前我們的項目要上一個消息中心黔寇,設(shè)計師看到京東的消息中心的cell側(cè)滑刪除比較好,就要求我們實現(xiàn)跟京東一模一樣的側(cè)滑刪除斩萌,這對于一年半之前我這樣的菜鳥來說缝裤,是一件比較頭疼的事情屏轰。不多說,現(xiàn)在整理一下憋飞,先看思路霎苗。
  • 第一步我們要對cell進行處理,創(chuàng)建一個scrollView上去搀崭,以便可以滑動
  • 其次放兩個View分別顯示內(nèi)容和顯示取消和刪除兩個按鈕叨粘,這里我使用代理方法實現(xiàn)監(jiān)控按鈕的點擊事件
  • 解決cell原生和scrollView的手勢沖突
  • 注意一點:當有cell處于編輯狀態(tài)時猾编,tableView是不可以滑動的瘤睹,這里跟原生的側(cè)滑刪除類似
現(xiàn)在看一下Demo代碼,這為了節(jié)省時間 cell我就用Xib拖了 Demo地址
  • cell的.m文件
 #import <UIKit/UIKit.h>
@protocol JDMessageCellDelegate;
@interface JDMessageCell : UITableViewCell
@property (nonatomic, assign) id<JDMessageCellDelegate> delegate;
//使用數(shù)據(jù)初始化cell 這里不一定是dictionary 也有可能是model
-(void)configCellWith:(NSDictionary *)dict;
// 判斷是否有cell處于編輯模式下
-(void)enableEditAction:(BOOL)canEdit;
//退出編輯模式
-(void)quitEditMode;
@end
  • 看一下需要實現(xiàn)的代理方法
@protocol JDMessageCellDelegate <NSObject>
//cell 開始編輯模式
-(void)cellBeginEditMode:(JDMessageCell *)cell;
// cell 結(jié)束編輯模式
-(void)cellEndEditMode:(JDMessageCell *)cell;
//刪除這條記錄
-(void)deleteMessageInCell:(JDMessageCell *)cell;
@end
  • 在.m文件中對聲明的方法和相對應(yīng)的屬性進行設(shè)置
#import "JDMessageCell.h"
@interface JDMessageCell ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *bgScrollView;
@property (weak, nonatomic) IBOutlet UIButton *cancelBtn;
@property (weak, nonatomic) IBOutlet UIButton *deleteBtn;
@property (weak, nonatomic) IBOutlet UIView *bgView;
@property (weak, nonatomic) IBOutlet UIView *leftView;
@property (weak, nonatomic) IBOutlet UILabel *leftTitleLabel;
@property (weak, nonatomic) IBOutlet UIImageView *leftImgView;
@property (weak, nonatomic) IBOutlet UIView *rightView;
@property (weak, nonatomic) IBOutlet UILabel *cancelLabel;
@property (weak, nonatomic) IBOutlet UILabel *deleteLabel;
@end
@implementation JDMessageCell
-(void)awakeFromNib {
    [super awakeFromNib];
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    //這些屬性都可以在Xib中設(shè)置 為了顯示設(shè)置了什么屬性寫了出來
    _bgScrollView.userInteractionEnabled = NO;
    _bgScrollView.bounces = NO;
    _bgScrollView.pagingEnabled = YES;
    _bgScrollView.delegate = self;
    //解決cell原生側(cè)滑刪除沖突
    [self.contentView addGestureRecognizer:_bgScrollView.panGestureRecognizer];
    _bgScrollView.contentSize = CGSizeMake(_bgScrollView.frame.size.width * 2, _bgScrollView.frame.size.height);
    //給cell的rightView空白區(qū)域添加個手勢
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(quitEditCell:)];
    tap.numberOfTapsRequired = 1;
    [self.rightView addGestureRecognizer:tap];
}
-(void)configCellWith:(NSDictionary *)dict {
    [_bgScrollView setContentOffset:CGPointZero animated:NO];
    _bgScrollView.userInteractionEnabled = NO;
}
-(void)enableEditAction:(BOOL)canEdit {
    if (canEdit) {
        [self.contentView addGestureRecognizer:_bgScrollView.panGestureRecognizer];
    }
    else {
        [self.contentView removeGestureRecognizer:_bgScrollView.panGestureRecognizer];
    }
}
//退出編輯模式
-(void)quitEditMode{
    [_bgScrollView setContentOffset:CGPointMake(0, 0) animated:YES];
    _bgScrollView.userInteractionEnabled = NO;
}
-(void)quitEditCell:(UITapGestureRecognizer *)gesture {
    [self quitEditMode];
    if (self.delegate && [self.delegate respondsToSelector:@selector(cellEndEditMode:)]) {
        [self.delegate cellEndEditMode:self];
    }
}
#pragma mark - UIScrollViewDelegate
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    CGFloat cellWidth = scrollView.frame.size.width;
    if (scrollView.contentOffset.x >= cellWidth / 2.0) {
        scrollView.userInteractionEnabled = YES;
        //此時cell處于編輯狀態(tài)
        if (self.delegate && [self.delegate respondsToSelector:@selector(cellBeginEditMode:)]) {
            [self.delegate cellBeginEditMode:self];
        }
    }
    else {
        scrollView.userInteractionEnabled = NO;
        //cell 退出編輯狀態(tài)
        if (self.delegate && [self.delegate respondsToSelector:@selector(cellEndEditMode:)]) {
            [self.delegate cellEndEditMode:self];
        }
    }
}
#pragma mark - Button Action
-(IBAction)cancelBtnAction:(id)sender {
    [self quitEditMode];
    if (self.delegate && [self.delegate respondsToSelector:@selector(cellEndEditMode:)]) {
        [self.delegate cellEndEditMode:self];
    }
}
-(IBAction)deleteBtnAction:(id)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(deleteMessageInCell:)]) {
        [self.delegate deleteMessageInCell:self];
    }
}
到這里cell的實現(xiàn)算是完成了答倡,下面就來看一下tableView的實現(xiàn)轰传,為了節(jié)省時間我就不單獨抽出來一個TableView了,直接在controller中開始寫了O(∩_∩)O哈哈~
  • 我這里只是一個demo沒有要公開出去的屬性和方法瘪撇,所以.h文件沒有東西就不寫了
  • 看一下.m文件吧 (我這里分組數(shù)和cell高度就寫死來演示了)
#import "ViewController.h"
#import "JDMessageCell.h"
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource, JDMessageCellDelegate> {
    JDMessageCell *cellAtMode; //正在編輯的cell
}
@property (weak, nonatomic) IBOutlet UITableView *jdTableView;
@end
@implementation ViewController
-(void)viewDidLoad {
    [super viewDidLoad];
    //register cell
    [_jdTableView registerNib:[UINib nibWithNibName:@"JDMessageCell" bundle:nil] forCellReuseIdentifier:@"JDMessageCell"];
}
#pragma mark -UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 4;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    JDMessageCell *jdCell = [tableView dequeueReusableCellWithIdentifier:@"JDMessageCell"];
//這個方法一定要使用获茬,如果不使用請寫一個公開的方法調(diào)用一下
    [jdCell configCellWith:[NSDictionary dictionary]];
    jdCell.delegate = self;
    return jdCell;
}
#pragma mark - UITableViewDelegate
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 201.0;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //如果存在正在編輯的cell 點擊其他的cell時,退出編輯
    if (cellAtMode) {
        [cellAtMode quitEditMode];
        [self enableTableViewEditAction:YES];
        cellAtMode = nil;
        NSLog(@"編輯退出");
    }
    else {
        NSLog(@"點擊了%ld組", indexPath.section);
    }
}
//這里是判斷tableView能不能滑動的倔既,當有cell處在編輯模式不能滑動
-(void)enableTableViewEditAction:(BOOL)enable {
    self.jdTableView.scrollEnabled = enable;
    for (NSInteger index = 0; index < self.jdTableView.numberOfSections; index++) {
        JDMessageCell *salesCell = [self.jdTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index]];
        [salesCell enableEditAction:enable];
    }
}
#pragma mark - JDMessageCellDelegate
//實現(xiàn)cell的代理方法
-(void)cellBeginEditMode:(JDMessageCell *)cell {
    [self enableTableViewEditAction:NO];
    [cell enableEditAction:YES];
    cellAtMode = cell;
}
//結(jié)束編輯了
-(void)cellEndEditMode:(JDMessageCell *)cell {
    [self enableTableViewEditAction:YES];
    cellAtMode = nil;
}
-(void)deleteMessageInCell:(JDMessageCell *)cell {
    NSInteger index = [self.jdTableView indexPathForCell:cell].section;
    [self removeCellAtIndex:index];
}
#pragma mark - Helper Method
-(void)removeCellAtIndex:(NSInteger)index {
    NSLog(@"刪除了第%ld組", index);
    //這里要看tableView是plain 還是grouped ->我這里使用的是分組形式的
}
-(void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
@end
寫到這里基本上就結(jié)束了恕曲,UI方面知識做了簡單的處理(比較難看 O(∩_∩)O哈哈~),相信結(jié)構(gòu)出來了渤涌,根據(jù)項目具體UI渲染不難吧佩谣。對于.m中的實現(xiàn)這里就不在細說了,代碼中有注釋实蓬,以上的代碼基本上滿足了項目中的需求茸俭,下面上幾張圖看一下
  • cell 的.xib 文件層級結(jié)構(gòu)圖
Cell層級結(jié)構(gòu).jpeg
  • 運行截屏
有一個cell正在編輯截圖.png
說明一下,本人程序菜鳥一枚安皱,這個Demo僅僅是滿足于項目的需求调鬓,相信京東的大神做的肯定比我的思路要簡單,而且代碼也比較優(yōu)雅酌伊,如果誰有更好的解決方法腾窝,歡迎留言交流。O(∩_∩)O哈哈~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末居砖,一起剝皮案震驚了整個濱河市虹脯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌悯蝉,老刑警劉巖归形,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鼻由,居然都是意外死亡暇榴,警方通過查閱死者的電腦和手機厚棵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔼紧,“玉大人婆硬,你說我怎么就攤上這事〖槔” “怎么了彬犯?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長查吊。 經(jīng)常有香客問我谐区,道長,這世上最難降的妖魔是什么逻卖? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任宋列,我火速辦了婚禮,結(jié)果婚禮上评也,老公的妹妹穿的比我還像新娘炼杖。我一直安慰自己,他們只是感情好盗迟,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布坤邪。 她就那樣靜靜地躺著,像睡著了一般罚缕。 火紅的嫁衣襯著肌膚如雪艇纺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天怕磨,我揣著相機與錄音喂饥,去河邊找鬼。 笑死肠鲫,一個胖子當著我的面吹牛员帮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播导饲,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼捞高,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渣锦?” 一聲冷哼從身側(cè)響起硝岗,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袋毙,沒想到半個月后型檀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡听盖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年胀溺,在試婚紗的時候發(fā)現(xiàn)自己被綠了裂七。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡仓坞,死狀恐怖背零,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情无埃,我是刑警寧澤徙瓶,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嫉称,受9級特大地震影響侦镇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜澎埠,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一虽缕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蒲稳,春花似錦、人聲如沸伍派。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诉植。三九已至祥国,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晾腔,已是汗流浹背舌稀。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灼擂,地道東北人壁查。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像剔应,于是被迫代替她去往敵國和親睡腿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

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