iOS-MMDrawerController的使用

作者: LitterL | 来源:发表于2016-03-22 14:41 被阅读13668次

    说明:

    最近在项目中需要实现一个抽屉效果,后来查了查资料觉得MMDrawerController还是比较不错的,下载下来试了一试MMDrawerController顺便做了一个小Demo,下图(希望能帮助大家):

    image

    这里的话我是直接使用的cocoapods,我就不详细介绍了,这里我就直接说Demo了,使用为纯代码

    代码:

    1、首先创建三个控制器为center、left、right(我这里就简写了,具体的话大家可以下载Demo),创建完成之后,我们来到我们的AppDelegate,开始编写我们的代码了

    • 1.1、多话不说,先导入头文件,并且添加一个MMDrawerController的属性
       //为MMDrawerController框架中
       #import "MMDrawerController.h"
       #import "UIViewController+MMDrawerController.h"
    
       //为自己创建的三个控制器
       #import "LitterLCenterViewController.h"
       #import "LitterLLeftViewController.h"
       #import "LitterLRightViewController.h"
    
       @interface LitterLAppDelegate ()
       /**
        *  MMDrawerController属性
        */
       @property(nonatomic,strong) MMDrawerController * drawerController;
       @end
    
    • 1.2、上面的做完后,我们便要显示我们的窗口到设备上,接下来来到这里
     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
       //1、初始化控制器
       UIViewController *centerVC = [[LitterLCenterViewController alloc]init];
       UIViewController *leftVC = [[LitterLLeftViewController alloc]init];
       UIViewController *rightVC = [[LitterLRightViewController alloc]init];
       //2、初始化导航控制器
       UINavigationController *centerNvaVC = [[UINavigationController alloc]initWithRootViewController:centerVC];
       UINavigationController *leftNvaVC = [[UINavigationController alloc]initWithRootViewController:leftVC];
       UINavigationController *rightNvaVC = [[UINavigationController alloc]initWithRootViewController:rightVC];
    
       //3、使用MMDrawerController
       self.drawerController = [[MMDrawerController alloc]initWithCenterViewController:centerNvaVC leftDrawerViewController:leftNvaVC rightDrawerViewController:rightNvaVC];
    
       //4、设置打开/关闭抽屉的手势
       self.drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureModeAll;
       self.drawerController.closeDrawerGestureModeMask =MMCloseDrawerGestureModeAll;
       //5、设置左右两边抽屉显示的多少
       self.drawerController.maximumLeftDrawerWidth = 200.0;
       self.drawerController.maximumRightDrawerWidth = 200.0;
    
       //6、初始化窗口、设置根控制器、显示窗口
       self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
       [self.window setRootViewController:self.drawerController];
       [self.window makeKeyAndVisible];
       return YES;
    }
    

    2、完成上面后基本的抽屉效果就已经实现了,在这里的话,我们将要实现导航栏上面的按钮,以及一些效果。

    • 2.1、这里的话我们先实现导航栏的效果吧:
    • 2.1.1、这里的话我用的是通过UIBarButtonItem的方法去实现的
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"menu"] style:UIBarButtonItemStylePlain target:self action:@selector(leftBtn)];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"navigationbar_friendattention"] style:UIBarButtonItemStylePlain target:self action:@selector(rightBtn)];
    
    • 2.1.2、然而我们的作者给了我们一个类,里面有他通过QuartzCore绘制出来的按钮,你们想看的话可以去看看
    //首先得导入头文件
    #import "MMDrawerBarButtonItem.h"
    //----------------------------
    self.navigationItem.leftBarButtonItem = [[MMDrawerBarButtonItem alloc]initWithTarget:self action:@selector(leftBtn)];
    self.navigationItem.rightBarButtonItem = [[MMDrawerBarButtonItem alloc]initWithTarget:self action:@selector(rightBtn)];
    
    • 2.1.3、这里的话就是我们的方法,其实很简单(就一行代码)但是过程很迷茫
    //首先得导入头文件
    #import "UIViewController+MMDrawerController.h"
    //----------------------------
    -(void)leftBtn{
    //这里的话是通过遍历循环拿到之前在AppDelegate中声明的那个MMDrawerController属性,然后判断是否为打开状态,如果是就关闭,否就是打开(初略解释,里面还有一些条件)
      [self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil];
    }
    -(void)rightBtn{
      [self.mm_drawerController toggleDrawerSide:MMDrawerSideRight animated:YES completion:nil];
    }
    
    • 2.2、完成上面后,导航栏的点击就能切换,那么我们就来实现一个效果吧,所谓的弹簧效果,也就几句代码
       //2、添加双击手势
       UITapGestureRecognizer * doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
       //2.1、双击
       [doubleTap setNumberOfTapsRequired:2];
       [self.view addGestureRecognizer:doubleTap];
    
       //3、添加两个手指双击手势
       UITapGestureRecognizer * twoFingerDoubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerDoubleTap:)];
       //3.1、双击
       [twoFingerDoubleTap setNumberOfTapsRequired:2];
       //3.2、两个手指  默认为一个
       [twoFingerDoubleTap setNumberOfTouchesRequired:2];
       [self.view addGestureRecognizer:twoFingerDoubleTap];
    
       //----------------------------
       /**
        *  添加点击手势  一个手指双击
        */
       -(void)doubleTap:(UITapGestureRecognizer*)gesture{
           [self.mm_drawerController bouncePreviewForDrawerSide:MMDrawerSideLeft completion:nil];
       }
    
       /**
        *  添加点击手势  两个个手指双击
        */
       -(void)twoFingerDoubleTap:(UITapGestureRecognizer*)gesture{
           [self.mm_drawerController bouncePreviewForDrawerSide:MMDrawerSideRight completion:nil];
       }
    

    3、到这里的话就是最后一步了,第一设置数据源,第二实现协议了。

    • 3.1、数据源的编写,这里的话我用的都是静态数据,就不做解释了,右侧和左侧抽屉都为一样的,你们自行查看吧
    #pragma mark - UITableViewDataSource
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 10;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
            static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.textLabel.text =[NSString stringWithFormat:@"Left-Demo%ld",indexPath.row];
        return cell;
    }
    
    • 3.2、这里就是我们的最后一步,点击Cell跳转控制器了,那么我们的有一个控制器取名去:LitterLShowViewController
    #pragma mark - UITableViewDelegate
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        LitterLShowViewController *showVC = [[LitterLShowViewController alloc]init];
        showVC.title = [NSString stringWithFormat:@"Left-Demo%ld",indexPath.row];
    
        //拿到我们的LitterLCenterViewController,让它去push
        UINavigationController* nav = (UINavigationController*)self.mm_drawerController.centerViewController;
        [nav pushViewController:showVC animated:NO];
        //当我们push成功之后,关闭我们的抽屉
        [self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) {
            //设置打开抽屉模式为MMOpenDrawerGestureModeNone,也就是没有任何效果。
            [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];
        }];
    }
    

    4、差点忘了一个,就是当我们的LitterLShowViewController退出后,我们的把打开抽屉模式在切换过来,当然这个是在中间控制器里面去写,因为LitterLShowViewController退出后会呈现中间控制器

    /**
     *  加载控制器的时候设置打开抽屉模式  (因为在后面会关闭)
     */
    -(void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
        //设置打开抽屉模式
        [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll];
    }
    

    Demo地址:MMDrawerControllerDemo

    本章到此结束
    欢迎各位码友随意转载并指正

    相关文章

      网友评论

      • 玫瑰花瓣的信笺:有蒙版层吗,打开抽屉的时候主视图展示蒙版效果,关闭抽屉式消除蒙版效果
        LitterL:左边按钮点击事件中写到
        [self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:^(BOOL finished) {
        UIView *view = [UIView new];
        view.backgroundColor = [UIColor redColor];
        view.frame = self.mm_drawerController.leftDrawerViewController.view.frame;
        [self.mm_drawerController.leftDrawerViewController.view addSubview:view];
        }];
        那个定义的view你就给它加点击事件把
        八百标兵奔北坡_283e:你好,蒙板的问题解决了吗??
      • iOS_:点击左侧的其中一个cell 收起MMdrawerControl是调用哪个方法
        LitterL:[self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) {
        //设置打开抽屉模式为MMOpenDrawerGestureModeNone,也就是没有任何效果。
        [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];
        }];
      • ea178e3dfb4b:用这个库怎么给滑出去的视图添加蒙版啊?有可以解惑的吗?
        八百标兵奔北坡_283e:你好,蒙板的问题解决了吗??
      • 小代码仔:大神 大神 pod 导入的不应该用尖括号的么,双引号为什么也可以?
      • 鄙人Joe:iOS11,左滑右滑卡顿,各位有遇到吗:hushed:
        鄙人Joe:有时间再换吧,多谢啦
        cw_:https://github.com/ChavezChen/CWLateralSlide 可以看看这个,一行代码集成0耦合侧滑框架:kissing_heart:
      • b869facd5ce7://当我们push成功之后,关闭我们的抽屉
        [self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) {
        //设置打开抽屉模式为MMOpenDrawerGestureModeNone,也就是没有任何效果。
        [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];
        }];

        没有循环引用么?:flushed:
      • 4d8b4b91fe29://拿到我们的LitterLCenterViewController,让它去push
        UINavigationController* nav = (UINavigationController*)self.mm_drawerController.centerViewController;
        [nav pushViewController:showVC animated:NO];

        关于这个有点不理解,为什么是拿到中间的去push呢?
        我现在有个问题,在左侧的控制器里面我是按照您的方法,拿到center去push的,但是在二级菜单,即左侧控制器的下一级,有个cell内部的按钮跳转,我是通过block传递到该二级菜单去跳转的,但是崩溃了。打印信息,当前控制器是mm_drawerController,这种情况该怎样去解决?急用...
        4d8b4b91fe29:在didSelectRowAtIndexPath里面跳转是没有问题的,只是cell内部按钮,通过block传递到vc,再跳转就出问题
      • 新地球说着一口陌生腔调:我现在遇到一个问题 Center 类中去push 一个Controller后 ,Center会被这个Controller替代掉?而我希望的是 过去的 Center保留不变,push进入一个新页面,
      • 瞬间看见永远:侧滑的动画效果怎么加
      • HanOBa:加了Tabbar tabbar不滑动啊。怎么破
      • HanOBa:楼主 留个Q 想问你个问题、
      • cmfish:多次打开菜单跳转中间页面再返回主页会出现bug
        有时候侧滑手势不响应有时候导航栏错位
      • 左耳进:作者你好,我有个问题,我现在需要侧滑后传值给leftView,怎么破解?
        左耳进:self.device = setVc.device; 是一个模型,也是属性传值
        左耳进:@LitterL 感谢,我已经解决了,下面是解决方法,另一种思路

        //这个是left控制器里
        - (void)viewWillAppear:(BOOL)animated{
        [self.tableView reloadData];

        UINavigationController *vc = (UINavigationController*)self.mm_drawerController.centerViewController;
        //中间的控制器
        PushTheWindowViewController * setVc = [vc.viewControllers objectAtIndex:0];//我需要的控制器是NavigationController 的第一个
        self.device = setVc.device;

        }
        LitterL:@菜鸟程序袁 你可以定义一个全局变量 在视图隐藏的时候赋值给他 或者 利用通知来检测
      • LJDeveloper:楼主有没有遇到过使用过程中侧滑事件偶尔失效,只能点击右上角按钮打开抽屉的情况?
      • 正义必胜biu:你好楼主,我想问怎么在跳转出去的时候保留当前的openside,返回的时候设置抽屉为上一次的openside
        正义必胜biu:@LitterL 好的。谢谢
        LitterL:@正义ing 你可以声明一个全局的变量用来储存
      • 走停2015_iOS开发:openDrawerGestureModeMask 这个属性 不好用 我设置为MMOpenDrawerGestureModeBezelPanningCenterView 但是不管用
      • __weak:楼主,请问打开抽屉后中心控制器怎么设置蒙版效果啊?
        __weak:楼主,再问你一下,摩拜单车的效果看起来是leftVc推出去的而centerVC不动,而你的效果是刚好相反,centerVC往右移而leftVC保持不动。我想问问怎样实现摩拜那种效果,是改根控制器吗?我试了一下好像有问题,现在弄得我都懵逼了。
        __weak:@LitterL 好的 谢谢你
        LitterL:这个我很久没有看了 可以试着自己写一层上去 添加到UIApplication.sharedApplication().keyWindow?.rootViewController?.view 这个上面 或者添加到指定的View上面都可以的
      • 刘建国大好人:您好,请问 tabbarcontroller作为中间控制器可以吗
        LitterL: 试一试就知道了
      • Kingiiyy_iOS:楼主.有一问题求助一下.点击显示left控制器的时候我点击跳转...跳转是从center的导航控制器往下push的... 这不是想要的效果喔...应该是从left控制器这边过去的都是重新创建的..并不是每一个都要从center控制器往下push . . . 不然每次往回退都是到center控制器! 求解 !
        Z了个Y:请教下楼主 如何在打开抽屉的时候给centerviewController设置蒙版
        LitterL:@kingiiyy 这个我倒是没有仔细去看过 因为之前的项目都是从中间视图push 左边更多的只用于筛选条件 或者展示信息 我不知道你的用意 是要用来干嘛 qq我私信你
        Kingiiyy_iOS:楼主QQ多少哦!一块讨论一下
      • 4999f4b4f3c4:这个SDK 支持ipv6吗?
        LitterL:支持的
      • ssim:你好,很感谢你的分享, 有个问题请教,如何监听抽屉完全打开?或者说是抽屉效果结束?
      • LJDeveloper:学习了
      • f036ff039df0:你好右滑那个弹动效果怎么去掉啊
      • 北港的海鸥:急 ! 楼主,左侧cell 点击push之后,返回到的时候 怎么不让侧滑栏隐藏。
      • 禾二十:楼主棒棒哒,完美解决了我遇到的问题
      • bb00ee197bde:楼主,我想问下,我项目首先是登陆界面,我的RootVc是login,登陆后,是项目整体框架的tabBarController,但是想用这个抽屉效果,就得把DraweVc设置为root,但是那样就没了tabBarController下所有的控制器,怎么解决下。。。。
        HanOBa:@DuYuGang 怎么解决的
        bb00ee197bde:@刘建国大好人 解决了,刚开始没有仔细看代码~:grin:
        刘建国大好人:请问 你解决了吗
      • 07f61e002279:为什么切换跟视图 就不能用了
      • Nbm:点击cell push到控制器时,那个抖动在哪里取消?
      • 阿拉斯加的狗:楼主 请问 请问你的demo 每次点击leftBtn 那个抽屉tableview就会抖动一下 怎么破 你的也有那个bug
        Nbm:@阿拉斯加的狗 哪个属性设置的,速求
        阿拉斯加的狗:@C平安是福 ok了..兄弟
        Nbm:请问你解决了吗?
      • 阿拉斯加的狗:楼主 请问 现在我要隐藏抽屉怎么办呢 在一个cenerVc中 隐藏leftVc 我找了没找到这个隐藏的办法. 求解释 感谢了
      • 884b9e293eb3:写的挺好的,赞一个
      • f9aa514b765d:楼主好人。我在centerVC里有个按钮push到B控制器,在B视图控制器里怎么关闭抽屉效果?
      • feng_dev:reside menu 是不是不能实现这种平的侧滑,好像 样式就那种固定了吗
      • feng_dev:reside menu 能实现这样的吗?
      • 十一遥:你的demo看完以后,有个问题,左边抽屉弹出的导航控制器, 在导航控制器,返回的时候,抽屉又回到了中间的控制器, 他不应该继续保留在左边抽屉打开的效果吗/
        ?
        FlameGrace:你可以在跳转出去的时候保留当前的openside,返回的时候设置抽屉为上一次的openside不就完了
      • Tamp_:按钮点击指南打开,但是不能关闭
      • 378aa42982b5:对啊 ,我也试过,不知道怎么解决
        LitterL:@陶帅强 你应该是在LitterLShowViewController这个控制器中像右滑动了一下 但是没有回到LitterLCenterViewController这个控制器中 然而你侧滑的时候会执行LitterLCenterViewController的viewWillAppear这个方法 在这个方法有 [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll]; 所有说 抽屉效果这个时候就会打开 只要你在LitterLShowViewController这个控制器中的viewWillAppear方法中加上[self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];这个之后 抽屉效果就会关闭
      • Echo126:作者你好,我有三个问题要问:1.你写的demo在点击左控制器cell push之后,侧滑没有关闭,这是为什么呢?2.我的主控制器是tabbarVC,它的每个子控制器都嵌套一个导航控制器。appdelegate里创建drawer时都是加了导航控制器的。我把tabbar的导航条隐藏了,这时左侧控制器push时,(按你的写法)是从tabbar导航push进去的。这时候我在pop出来刚才的控制器导航条会黑一下。3.setOpenDrawerGestureModeMask =MMOpenDrawerGestureModeAll 和MMCloseDrawerGestureMode =MMCloseDrawerGestureModeNone 是等价的吗?不太懂打开和关闭分别设置有什么用?
        LitterL:@Echo126 你应该是在LitterLShowViewController这个控制器中像右滑动了一下 但是没有回到LitterLCenterViewController这个控制器中 然而你侧滑的时候会执行LitterLCenterViewController的viewWillAppear这个方法 在这个方法有 [self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll]; 所有说 抽屉效果这个时候就会打开 只要你在LitterLShowViewController这个控制器中的viewWillAppear方法中加上[self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];这个之后 抽屉效果就会关闭
        Echo126:setOpenDrawerGestureModeMask 设置成MMOpenDrawerGestureModeAll 和setCloseDrawerGestureModeMask 设置成 MMCloseDrawerGestureModeNone 有什么区别?他俩不是相对的吗?不知道何时设置setOpenDrawerGestureModeMask何时设置setCloseDrawerGestureModeMask?而且我刚按照你说的在push后的控制器LitterLShowViewController写了LitterLShowViewController写了[self.mm_drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];还是有侧滑。现在做这块,可能有很多问题要问。作者能不能发我一个比较完整的demo?
        LitterL:@Echo126
        不好意思
        第一个的话 是我忘记了一个问题 cell push之后 进入ShowViewController 然而你轻轻往右滑动的时候 其实它已经加载了centerViewController控制器中的viewWillAppear这个方法,这个方法打开了打开抽屉模式 如果想解决 那么你在ShowViewController的viewWillAppear这个方法中加上关闭抽屉模式就可以了
        第二个 也许是你隐藏的时间的问题 你可以在push这个界面快要消失的时候 你就隐藏tabbar
        第三个 它们的打开和关闭 其实是在所有界面都有效的 因为开始的时候就加载了抽屉 然后你每一界面都是收到抽屉模式的控制 你可以选择性的打开或者关闭这个效果
      • 开水里的面条:加上tabbarcontroller 就会蹦
        e8923c619f43:@开水里的面条 解决了么
        开水里的面条:@LitterL 肯定tabbar
        根控制器
        LitterL:@0ea2d9678241 你用tabbarcontroller为根控制吗 还是怎么
      • 单腿行走的大象:谢谢楼主分享,之前项目用的是PPRevealSideViewController这个框架,15年就停止更新了,网上关于PPRevealSideViewController内容也少,今天换成了楼主用的这个框架,受益匪浅.3q
        LitterL:@单腿行走的大象 :blush: :blush: :blush:
      • 凯撒牛:你好是不是MMDrawercontroller这个类初始化必须在appdelegate那个方法里面 我现在需要做的是进来的时候是登录界面 所以不能再这里初始化
        hhgvg:@纵横小浩 你把cenvc重新设置成root
        纵横小二: LoginController *loginVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"login"];
        self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
        [self.window setRootViewController:loginVC];
        [self.window makeKeyAndVisible];
        首先显示登录页面,点击登陆后跳到centerVC页面,这时候抽屉就没有效果了。怎么破?
        LitterL:@凯撒牛 这个的话 是可以的 你登录成功了 改变它的根控制器就可以了
      • VoiderSun:楼主请教一个问题,我首页没有导航栏,抽屉也没有导航栏,怎么push到下一个cell?
        VoiderSun:@LitterL 我中间加了导航控制器是可以push的,但是怎么不加也可以push呢?
        VoiderSun:@LitterL 我中间视图没有导航控制器,我左视图可以加一个导航控制器,这样可以push吗?
        LitterL:@VoiderSun 有导航控制器吗 如果没有导航控制器是不能够Push的
      • Sanchain:谢谢楼主分享,学习了 :smiley:
      • Theyouth:终于找到抽屉的库了
        LitterL:@Theyouth 😄😄😄 希望能帮助你

      本文标题:iOS-MMDrawerController的使用

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