iOS UITableView配合block 回调实现列表删除教程

前言:

各位同学大家好 ,有段时间没有给大家更新文章了 。 具体多久我也记不清楚了,春节放假比较早,所以就趁着有时间学习了一下iOS开发的基础知识 今天讲的iOS UITableView 配和block 回调实现列表删除教程 。那么废话不多说 ,我们正式开始。

准备工作

安装xcode 这个大家可以自己去appstore 搜索下载安装即可

效果图

QQ20210210-160354-HD[00_00_00--00_00_08].gif

具体实现

  • 列表显示
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,GTNotmalTableViewDelegate>
@property(nonatomic,strong,readwrite)UITableView * tableview;
@property(nonatomic,strong,readwrite)NSMutableArray * dataArray;
@end
@implementation ViewController
- (instancetype)init{
    self= [super init];
    if(self){
        _dataArray=@[].mutableCopy;
        for(int i=0; i<20;i++){
            [_dataArray addObject:@(i)];
        } 
    }
    return  self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor= [UIColor whiteColor];
    _tableview= [[UITableView alloc]initWithFrame:self.view.bounds];
    _tableview.dataSource=self;
    _tableview.delegate=self;
    [self.view addSubview:_tableview];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 110 ;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"%ld", indexPath.row)
    
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return _dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
  //UItableview cell 复用机制
    GTNormalTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
    if(!cell){
    cell =[[GTNormalTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
                                reuseIdentifier:@"id"];
        cell.deledate=self;
    }
    [cell layoutTableViewCell];
    return  cell;
}
- (void) tableviewCell:(UITableViewCell *)tabviewCell clickDeleteButton:(UIButton * )deletebutton{
    NSLog(@"clickDeleteButton");
    GTDeleteCellView * deleteview =[[GTDeleteCellView alloc] initWithFrame:self.view.bounds];
    CGRect  rect =[tabviewCell  convertRect:deletebutton.frame  toView:nil];
    __weak typeof(self)wself= self;
    [deleteview showDeleteViewFromPoint:rect.origin clickBlock:^{
        __strong typeof  (self)strongSelf=wself;
        [strongSelf.dataArray removeLastObject];
        NSLog(@"clickBlock  回调");
        [self.tableview deleteRowsAtIndexPaths:@[[strongSelf.tableview indexPathForCell:tabviewCell]]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
    
    } ];

}
@end

我们这边调用系统的 UITableView 组件 实例化 然后添加自定义的cell 来实现 整个列表的展示

  • 添加自定义的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  //UItableview cell 复用机制
    GTNormalTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
    if(!cell){
    cell =[[GTNormalTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
                                reuseIdentifier:@"id"];
        cell.deledate=self;
    }
    [cell  layoutTableViewCell];
    return  cell;
}
  • 自定义 cell 内容
//
//  GTNormalTableViewCell.m
//  shop
//
//  Created by xuqing on 2021/1/27.
//  Copyright © 2021 xuqing. All rights reserved.
//
#import "GTNormalTableViewCell.h"
@interface GTNormalTableViewCell()
@property(nonatomic,strong,readwrite)UILabel * titleLable;
@property(nonatomic,strong,readwrite)UILabel * sourceLable;
@property(nonatomic,strong,readwrite)UILabel * commentLable;
@property(nonatomic,strong,readwrite)UILabel * timeLable;
@property(nonatomic,strong,readwrite)UIImageView *richtimageview;
@property(nonatomic,strong,readwrite)UIButton* deletebutton;
@end

@implementation GTNormalTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)
      reuseIdentifier {
    self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if(self){
        [self.contentView addSubview:({
            self.titleLable=[[UILabel alloc]initWithFrame:CGRectMake(20, 15, 300, 50)];
           // self.titleLable.backgroundColor=[UIColor redColor];
            self.titleLable;
        })];
        [self.contentView addSubview:({
            self.sourceLable=[[UILabel alloc]initWithFrame:CGRectMake(20, 80, 50, 20)];
          //  self.sourceLable.backgroundColor=[UIColor redColor];
            self.sourceLable;


        })];
        [self.contentView addSubview:({
            self.commentLable=[[UILabel alloc]initWithFrame:CGRectMake(100 ,80, 50, 20)];
           // self.commentLable.backgroundColor=[UIColor redColor];
            self.commentLable;
        })];


        [self.contentView addSubview:({
            self.timeLable=[[UILabel alloc]initWithFrame:CGRectMake(150, 80, 50, 20)];
          //  self.timeLable.backgroundColor=[UIColor redColor];
            self.timeLable;
        })];
        
        
        [self.contentView addSubview:({
            self.richtimageview=[[UIImageView alloc]initWithFrame:CGRectMake(330, 15, 70, 70)];
            self.richtimageview.backgroundColor=[UIColor redColor];
            self.richtimageview;
        })];
        
        
        [self.contentView addSubview:({
            self.deletebutton=[[UIButton alloc]initWithFrame:CGRectMake(290, 80, 30,20)];
            self.deletebutton.backgroundColor=[UIColor blueColor];
            [self.deletebutton setTitle:@"X" forState:UIControlStateNormal];
            [self.deletebutton setTitle:@"V" forState:UIControlStateHighlighted];
            [self.deletebutton addTarget:self action:@selector(deletebuttonClick) forControlEvents:UIControlEventTouchUpInside];
            
            self.deletebutton;
        })];
    
    }
    return  self;
}


- (void)layoutTableViewCell{
    self.titleLable.text=@"极客时间iOS开发";
    self.sourceLable.text=@"极客时间";
    [self.sourceLable sizeToFit];

    self.commentLable.text=@"1999评论";
    [self.commentLable sizeToFit];
    self.commentLable.frame= CGRectMake(self.sourceLable.frame.origin.x+self.commentLable.frame.size.width+15,
                                        self.commentLable.frame.origin.y,   self.commentLable.frame.size.width, self.commentLable.frame.size.height);
    self.timeLable.text=@"三分钟前";
    [self.timeLable sizeToFit];
    self.timeLable.frame= CGRectMake(self.commentLable.frame.origin.x+self.commentLable.frame.size.width+15,
                                     self.timeLable.frame.origin.y,   self.timeLable.frame.size.width, self.timeLable.frame.size.height);
}
- (void)deletebuttonClick{
    NSLog(@"deletebuttonClick");
    if(self.deledate &&[self.deledate respondsToSelector:@selector(tableviewCell:clickDeleteButton:)]){
        [self.deledate tableviewCell:self clickDeleteButton:self.deletebutton];
    }
}
@end

为我们的删除按钮添加点击onClick 事件

[self.deletebutton addTarget:self action:@selector(deletebuttonClick) forControlEvents:UIControlEventTouchUpInside];
  • 具体点击事件
- (void)deletebuttonClick{
    NSLog(@"deletebuttonClick");
    if(self.deledate &&[self.deledate respondsToSelector:@selector(tableviewCell:clickDeleteButton:)]){
        [self.deledate tableviewCell:self clickDeleteButton:self.deletebutton];
    }
}

我们在cell子布局里面的删除按钮的点击事件调用了 clickDeleteButton 方法

@protocol GTNotmalTableViewDelegate <NSObject>
- (void) tableviewCell:(UITableViewCell *)tabviewCell clickDeleteButton:(UIButton * )deletebutton;
@end

然后 我们在ViewController 中实现clickDeleteButton 方法

- (void) tableviewCell:(UITableViewCell *)tabviewCell clickDeleteButton:(UIButton * )deletebutton{
    NSLog(@"clickDeleteButton");
    GTDeleteCellView * deleteview =[[GTDeleteCellView alloc] initWithFrame:self.view.bounds];
    CGRect  rect =[tabviewCell  convertRect:deletebutton.frame  toView:nil];
    __weak typeof(self)wself= self;
    [deleteview showDeleteViewFromPoint:rect.origin clickBlock:^{
        __strong typeof  (self)strongSelf=wself;
        [strongSelf.dataArray removeLastObject];
        NSLog(@"clickBlock  回调");
        [self.tableview deleteRowsAtIndexPaths:@[[strongSelf.tableview indexPathForCell:tabviewCell]]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
    } ];
}

我们在 clickDeleteButton 方法中初始化GTDeleteCellView 并显示

  • 弹出 GTDeleteCellView 具体实现
- (instancetype) initWithFrame:(CGRect)frame{
    
    self= [super initWithFrame:frame];
    if(self){
        
       [self addSubview:({
           _backgroundView=[[UIView alloc]initWithFrame:self.bounds];
           _backgroundView.backgroundColor=[UIColor blackColor];
           _backgroundView.alpha=0.5;
           [_backgroundView addGestureRecognizer:({
               UITapGestureRecognizer * tapGesture= [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(dismissDeleteView)];
               tapGesture;
           })];
           _backgroundView;
       })];
        [self addSubview:({
            _deleteButton=[[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 50)];
            _deleteButton.titleLabel.textColor = [UIColor whiteColor];
            _deleteButton.titleLabel.text=@"删除";
            [_deleteButton addTarget:self action:@selector(_clickButton) forControlEvents:UIControlEventTouchUpInside];
            _deleteButton.backgroundColor=[UIColor redColor];
           _deleteButton;
        })];
    }
    return  self;
}

GTDeleteCellView 的显示和关闭

  • 显示

-(void)showDeleteViewFromPoint:(CGPoint)point  clickBlock:(dispatch_block_t)clickBlock{
    _deleteButton.frame=CGRectMake(point.x, point.y, 0, 0);
    _deleteBlock=[clickBlock copy];
    UIWindow *window =  [[[UIApplication sharedApplication] windows] objectAtIndex:0];
    [window addSubview:self];
  //  [[UIApplication sharedApplication].keyWindow addSubview:self];
//   [UIView animateWithDuration:1.f animations:^{
//       self.deleteButton.frame=CGRectMake((self.bounds.size.width-200)/2 , (self.bounds.size.height-200)/2, 200, 200);
//   }];
//
    [UIView animateWithDuration:1.f delay:0.f usingSpringWithDamping:0.5  initialSpringVelocity:0.5 options:UIViewAnimationCurveEaseInOut
                     animations:^{
     self.deleteButton.frame=CGRectMake((self.bounds.size.width-200)/2 , (self.bounds.size.height-200)/2, 200, 200);
 }completion:^(BOOL finished){
  
     NSLog(@"completion");
   
 }];
  
}

showDeleteViewFromPoint 方法需要外部传入 CGPoint 和block 的回调实现 然后showDeleteViewFromPoint 方法里面我们处理 GTDeleteCellView 弹出的的动画效果

  • 动画
 [UIView animateWithDuration:1.f delay:0.f usingSpringWithDamping:0.5  initialSpringVelocity:0.5 options:UIViewAnimationCurveEaseInOut
                     animations:^{
     self.deleteButton.frame=CGRectMake((self.bounds.size.width-200)/2 , (self.bounds.size.height-200)/2, 200, 200);
 }completion:^(BOOL finished){
     NSLog(@"completion");
 }];

实例化block 和point

    _deleteButton.frame=CGRectMake(point.x, point.y, 0, 0);
    _deleteBlock=[clickBlock copy];
    UIWindow *window =  [[[UIApplication sharedApplication] windows] objectAtIndex:0];
    [window addSubview:self];
  • 关闭

-(void)dismissDeleteView{
    [self removeFromSuperview];
}

这是点空白的地方关闭
我们给deletebutton 添加点击事件

  [_deleteButton addTarget:self action:@selector(_clickButton) forControlEvents:UIControlEventTouchUpInside];

我们在点击事件方法实现里面 调用 block和 removeFromSuperview

-(void)_clickButton{
 //   _deleteBlock();
    if(_deleteBlock){
        _deleteBlock();
        NSLog(@"block回调执行");
    }
    [self removeFromSuperview];
}

这样我们的deletebutton点击就也会关闭 GTDeleteCellView
然后我们在 ViewController 中将block 的会回调实现 并且删除dataArray数组里面的数据更新列表

CGRect  rect =[tabviewCell  convertRect:deletebutton.frame  toView:nil];
    __weak typeof(self)wself= self;
    [deleteview showDeleteViewFromPoint:rect.origin clickBlock:^{
        __strong typeof  (self)strongSelf=wself;
        [strongSelf.dataArray removeLastObject];
        NSLog(@"clickBlock  回调");
        [self.tableview deleteRowsAtIndexPaths:@[[strongSelf.tableview indexPathForCell:tabviewCell]]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
    
    } ];

我们调用 GTDeleteCellView 中的showDeleteViewFromPoint 方法传入我们转换后的point 和block 的实现
最后我们调用

 [strongSelf.dataArray removeLastObject];

删除数组里面的数据 然后调用 deleteRowsAtIndexPaths删除并刷新列表

 [self.tableview deleteRowsAtIndexPaths:@[[strongSelf.tableview indexPathForCell:tabviewCell]]
                              withRowAnimation:UITableViewRowAnimationAutomatic];

到此iOS UITableView配合block 回调实现列表删除教程就讲完了

最后总结

在iOS开发中这种列表展示基本都是使用 UITableView 和UICollectionView 我这边只是加单举例所以直接就用UITableView 实现了 我们要注意的是block回调使用和动画的处理 以及自定义cell的处理 就差不多了 ,我是一名安卓程序员 因为需要就来学习一下iOS的开发, 最近看了一下教程学习了IOS里面的一些基础控件的用法。 就想着做个笔记 所以就写了这篇文章 ,记录一下 如果有错误的请大神们指出。 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容