美文网首页iOS工作系列iOS开发控件类
UITableView的左滑多菜单自定义

UITableView的左滑多菜单自定义

作者: CGPointZero | 来源:发表于2016-01-11 12:22 被阅读2091次

    前言:

    好久没写点什么了,今天来一发,表视图的左滑删除菜单的自定义。由于UITableView自带的左滑菜单只有“删除”,并且不能修改。因此,想要作出那种左滑出来有多个菜单的,就必须自定义cell。

    先上效果图

    效果截图

    说下思路:

    1.自定义cell
    2.在cell上搞一个视图作为容器
    3.在cell的contentView上添加好左滑出来的菜单
    4.添加容器视图,遮挡菜单
    5.在容器视图上添加自定义的其它视图
    6.给容器视图上添加左右滑动手势,以开闭cell的左滑菜单
    7.在cell里搞一个接口,关闭左滑菜单。因为你在左滑开启菜单时,其它的cell的菜单应当关闭。

    效果图

    下面看代码:

    AppDelegate.m
    <pre>
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //搞个导航
    ViewController *vc=[[ViewController alloc]init];
    UINavigationController *navi=[[UINavigationController alloc]initWithRootViewController:vc];
    navi.navigationBar.barStyle=UIBarStyleBlack;
    self.window.rootViewController=navi;
    return YES;
    }
    </pre>
    TestCell.h
    <pre>

    import <UIKit/UIKit.h>

    @interface TestCell : UITableViewCell

    /**标记左滑菜单是否打开*/
    @property(nonatomic,assign,readonly)BOOL isOpen;
    /**测试文字*/
    @property(nonatomic,strong)UILabel *testLb;
    /**取消关注的回调*/
    @property(nonatomic,copy)void (^cancelCallBack)();
    /**删除的回调*/
    @property(nonatomic,copy)void (^deleteCallBack)();
    /**左后滑动的回调*/
    @property(nonatomic,copy)void (^swipCallBack)();

    /**
    * 关闭左滑菜单
    * completionHandle 完成后的回调
    */
    -(void)closeMenuWithCompletionHandle:(void (^)(void))completionHandle
    @end
    </pre>

    TestCell.m
    <pre>

    import "TestCell.h"

    @interface TestCell()

    @property(nonatomic,strong)UIView *containerView;

    @end

    @implementation TestCell

    define kWidth [UIScreen mainScreen].bounds.size.width

    define kHeight [UIScreen mainScreen].bounds.size.height

    -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
    if(self=[super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {
    for(UIView *sub in self.contentView.subviews)
    {
    [sub removeFromSuperview];
    }
    [self createUI];
    }
    return self;
    }
    //创建UI
    -(void)createUI
    {
    //取消关注按钮
    UIButton *cancelBtn=[[UIButton alloc]initWithFrame:CGRectMake(kWidth-100, 0, 50, 50)];
    cancelBtn.backgroundColor=[UIColor grayColor];
    [cancelBtn setTitle:@"取消\n关注" forState:UIControlStateNormal];
    cancelBtn.titleLabel.numberOfLines=0;
    cancelBtn.titleLabel.font=[UIFont systemFontOfSize:12];
    [cancelBtn addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside];

    //删除按钮
    UIButton \*deleteBtn=[[UIButton alloc]initWithFrame:CGRectMake(kWidth-50, 0, 50, 50)];
    [deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
    deleteBtn.backgroundColor=[UIColor redColor];
    [deleteBtn addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside];
    
    [self.contentView addSubview:cancelBtn];
    [self.contentView addSubview:deleteBtn];
    
    //容器视图
    _containerView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, kWidth, 50)];
    _containerView.backgroundColor=[UIColor whiteColor];
    [self.contentView addSubview:_containerView];
    if(_isOpen)
        _containerView.center=CGPointMake(kWidth/2-100, _containerView.center.y);
    
    //测试Label
    _testLb=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, kWidth-20, 50)];
    [_containerView addSubview:_testLb];
    _testLb.text=@"我是左滑测试文字~";
    _testLb.backgroundColor=[UIColor whiteColor];
    
    //添加左滑手势
    UISwipeGestureRecognizer \*swipLeft=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swip:)];
    swipLeft.direction=UISwipeGestureRecognizerDirectionLeft;
    [_containerView addGestureRecognizer:swipLeft];
    
    //添加右滑手势
    UISwipeGestureRecognizer \*swipRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swip:)];
    swipRight.direction=UISwipeGestureRecognizerDirectionRight;
    [_containerView addGestureRecognizer:swipRight];
    

    }
    /**取消关注*/
    -(void)cancelAction
    {
    if(self.cancelCallBack)
    self.cancelCallBack();
    }
    /**删除*/
    -(void)deleteAction
    {
    if(self.deleteCallBack)
    self.deleteCallBack();
    }
    /*滑动手势/
    -(void)swip:(UISwipeGestureRecognizer *)sender
    {
    //滑动的回调
    if(self.swipCallBack)
    self.swipCallBack();
    //左滑
    if(sender.direction==UISwipeGestureRecognizerDirectionLeft)
    {
    if(_isOpen)
    return;
    [UIView animateWithDuration:0.3 animations:^{
    sender.view.center=CGPointMake(sender.view.center.x-100, sender.view.center.y);
    }];
    _isOpen=YES;
    }
    //右滑
    else if(sender.direction==UISwipeGestureRecognizerDirectionRight)
    {
    if(!_isOpen)
    return;
    [UIView animateWithDuration:0.3 animations:^{
    sender.view.center=CGPointMake(kWidth/2, sender.view.center.y);
    }];
    _isOpen=NO;
    }
    }
    /**关闭左滑菜单*/
    -(void)closeMenuWithCompletionHandle:(void (^)(void))completionHandle
    {
    if(!_isOpen)
    return;
    __weak typeof(self) wkSelf=self;
    [UIView animateWithDuration:0.3 animations:^{
    wkSelf.containerView.center=CGPointMake(kWidth/2, wkSelf.containerView.center.y);
    }completion:^(BOOL finished) {
    if(completionHandle)
    completionHandle();
    }];
    _isOpen=NO;
    }
    @end
    </pre>

    ViewController.m
    <pre>
    #import "ViewController.h"
    #import "TestCell.h"

    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>

    @property(nonatomic,strong)UITableView *tbView;
    @property(nonatomic,strong)NSMutableArray *dataArray;

    @end

    #define kWidth [UIScreen mainScreen].bounds.size.width
    #define kHeight [UIScreen mainScreen].bounds.size.height

    @implementation ViewController

    - (void)viewDidLoad
    {
    [super viewDidLoad];
    [self setup];
    [self createTableView];

    }
    /**创建表视图*/
    -(void)createTableView
    {
    _tbView=[[UITableView alloc]initWithFrame:CGRectMake(0, 64, kWidth, kHeight-64) style:UITableViewStylePlain];
    _tbView.delegate=self;
    _tbView.dataSource=self;
    [self.view addSubview:_tbView];
    }
    /**初始化*/
    -(void)setup
    {
    self.view.backgroundColor=[UIColor whiteColor];
    self.title=@"自定义左滑测试";
    self.automaticallyAdjustsScrollViewInsets=NO;

    _dataArray=[NSMutableArray array];
    [_dataArray addObjectsFromArray:@[@"测试文字1哈哈😄",@"测试文字2嘿嘿😱",@"测试文字3呵呵😂",@"测试文字4哦哦👻",@"测试文字5额额😁"]];
    

    }
    #pragma mark - UITableView
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    return _dataArray.count;
    }
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    static NSString *const cid=@"cid";
    TestCell *cell=[tableView dequeueReusableCellWithIdentifier:cid];
    if(!cell)
    cell=[[TestCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cid];
    cell.selectionStyle=UITableViewCellSelectionStyleNone;
    cell.testLb.text=_dataArray[indexPath.row];
    __weak typeof(self) wkSelf=self;
    __weak typeof(cell) wkCell=cell;
    //取消关注的回调
    cell.cancelCallBack=^{
    //关闭菜单
    [wkCell closeMenuWithCompletionHandle:^{
    //发送取消关注的请求
    //若请求成功,则从数据源中删除以及从界面删除
    [wkSelf.dataArray removeObjectAtIndex:indexPath.row];
    [wkSelf.tbView reloadData];

        }];
    };
    //删除的回调
    cell.deleteCallBack=^{
        //关闭菜单
        [wkCell closeMenuWithCompletionHandle:^{
            //发送删除请求
            //若请求成功,则从数据源中删除以及从界面删除
            [wkSelf.dataArray removeObjectAtIndex:indexPath.row];
            [wkSelf.tbView reloadData];
        }];
    };
    //左右滑动的回调
    cell.swipCallBack=^{
        for(TestCell *tmpCell in tableView.visibleCells)
            [tmpCell closeMenuWithCompletionHandle:nil];
    };
    return cell;
    

    }
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    return 50;
    }
    @end
    </pre>
    最后附上GitHub上这个Demo的GitHub源码地址,希望多多支持!

    相关文章

      网友评论

      • Rui哥:👍👍👍@CGPointZero 谢谢你的分享,顺便问下你这个手机录制的视频怎么转换成gif 的呢,可以指教一下不
        Rui哥:@CGPointZero 多谢
        CGPointZero:@Rui哥 有个软件叫PicGif
      • 喵子G:"由于UITableView自带的左滑菜单只有“删除”,并且不能修改。"
        UITableView的左滑菜单是可以修改的,并且使用的是UITableViewDelegate提供现成的方法- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath。
        CGPointZero:@黑山老猫 这个方法只能在iOS 8及之后使用,iOS只能自定义了http://www.jianshu.com/p/67dfa3cd349d
      • 谈daxia:你好,效果很棒!我想问下,这段代码是起什么作用的,一时没看懂?:
        文/CGPointZero(简书作者)
        原文链接:http://www.jianshu.com/p/05e38d2df445
        著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

        //左右滑动的回调
        cell.swipCallBack=^{
        for(TestCell *tmpCell in tableView.visibleCells)
        [tmpCell closeMenuWithCompletionHandle:nil];
        };
        CGPointZero:@谈daxia 目的是你在左滑打开下一个时,把上一个左滑打开的cell关闭掉
      • CGPointZero:有不懂的可以联系我

      本文标题:UITableView的左滑多菜单自定义

      本文链接:https://www.haomeiwen.com/subject/oabqkttx.html