**MenuViewController.h文件**
#import <UIKit/UIKit.h>
@interface MenuViewController : UIViewController
//左边抽屉控制器,受Menu的左边视图
@property(nonatomic,strong)UIViewController *leftVC;
//根视图控制器:受Menu管理的根视图
@property(nonatomic,strong)UIViewController *rootVC;
//记录抽屉是否打开,默认值是关闭
@property(nonatomic,assign)BOOL isDisplayMenu;
//带一个根视图控制器的初始化方法
//返回一个带根视图控制器的Menu实例
-(instancetype)initWithRootViewController:(UIViewController *)controller;
@end
MenuViewController.m文件**重点内容**
#import "MenuViewController.h"
@interface MenuViewController ()
//手势
@property(nonatomic,strong)UISwipeGestureRecognizer *leftSwipe;
@property(nonatomic,strong)UISwipeGestureRecognizer *rightSwipe;
@end
@implementation MenuViewController
//7:显示与隐藏的功能写好了,现在在添加两个手势 分别调用两个方法就可以了,注意手势要加在根视图控制器的view上面,手势在延展里面声明属性
- (void)viewDidLoad {
[super viewDidLoad];
// self.view.backgroundColor = [UIColor redColor];
[self setDefaultMenuImage];//
self.isDisplayMenu = NO;//一开始是关闭的
//初始化向左扫和向右扫的手势
//左滑
self.leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doLeftAction:)];
self.leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
[self.rootVC.view addGestureRecognizer:self.leftSwipe];
//右滑(系统默认就是向右边轻扫)
self.rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doRightAction:)];
[self.rootVC.view addGestureRecognizer:self.rightSwipe];
}
//再实现两个手势绑定的方法(分别调用显示与隐藏的方法就好了)
#pragma -mark 向左边手势方法
-(void)doLeftAction:(UISwipeGestureRecognizer *)left
{
[self hideen];
}
-(void)doRightAction:(UISwipeGestureRecognizer *)right
{
[self show];
}
//1.先实现根控制器的初始化方法
-(instancetype)initWithRootViewController:(UIViewController *)controller
{
if (self = [super init]) {
self.rootVC = controller;
}
return self;
}
//2.重写左边视图的setter方法
-(void)setLeftVC:(UIViewController *)leftVC
{
_leftVC = leftVC;
}
//3.重写根视图控制器的方法
-(void)setRootVC:(UIViewController *)rootVC
{
//对根视图赋值
_rootVC = rootVC;
//先判断根视图是否为空,不为空才能进行操作
if (_rootVC) {
//将根视图控制器的视图取出来
UIView *view = _rootVC.view;
view.frame = self.view.bounds;
[self.view addSubview:view];//把根视图的view放在菜单上面
//添加手势
[view addGestureRecognizer:self.leftSwipe];
[view addGestureRecognizer:self.rightSwipe];
[self setDefaultMenuImage];
}
}
//4.给导航栏的左边按钮添加一张默认的图片
#pragma -mark 为菜单按钮设置图片
/*
这里设置导航栏的菜单按钮默认图片,但是有可能没有导航栏 所以需要加上判断
*/
-(void)setDefaultMenuImage
{
//1.先判断有没有根视图控制器
if (self.rootVC == nil) {
return;
}
//2.判断根视图控制器是否为导航控制器 因为只有导航控制器才有nvgationBar
if ([self.rootVC isKindOfClass:[UINavigationController class]]) {
//注意:设置item的时候要使用当前的视图控制器去 设置,并不是使用导航控制器取设置,做法就是先得到导航控制器,再从导航控制器管理的视图控制器数组中得到当前的的视图控制器,这时就可以设置了
//2.1为菜单的导航控制器创建一个barButtonItem
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"666"] style:UIBarButtonItemStylePlain target:self action:@selector(leftBarButtonAction:)];
//2.2先拿到导航控制器
UINavigationController *firstNav = (UINavigationController *)self.rootVC;
//2.3再从导航控制器管理的控制器中取出第一个控制器
UIViewController *first = [[firstNav viewControllers] objectAtIndex:0];
//2.4给导航栏左边按钮赋值
first.navigationItem.leftBarButtonItem = leftBarButtonItem;
}
}
//5.实现左边按钮的绑定方法,在这个方法里面只要判断当前的左边视图是否被打开(显示与隐藏的方法写在下面,这里先直接调用)
//菜单左边按钮执行的方法
-(void)leftBarButtonAction:(UIBarButtonItem *)leftItem
{
//先判断当前是打开还是关闭
if (self.isDisplayMenu == NO) {
[self show];
}else
{
[self hideen];
}
}
//6实现显示与隐藏左边视图的方法
/*思路:先拿到左边抽屉的视图的view,在设置frame因为左边视图只会显示一部分
注意点就是拿到的view不能直接addsubview上去,而是要使用insertSubview:atlindex插入,否则会出现别的效果
*/
#pragma mark 显示左边菜单
-(void)show
{
//1.拿到左边抽屉的视图
UIView *leftView = self.leftVC.view;
CGRect frame = self.view.frame;
frame.size.width = 100;
//2.设置菜单的大小,宽度为100
leftView.frame = frame;
//3.要用插入,因为左边的菜单要在menu的视图下面
[self.view insertSubview:leftView atIndex:0];
//(2)第二大步:移动菜单的根视图
frame = _rootVC.view.frame;//重新赋值
frame.origin.x = 100;
[UIView animateWithDuration:1 animations:^{
_rootVC.view.frame = frame;
self.isDisplayMenu = YES;
}];
}
#pragma mark 隐藏左边菜单
-(void)hideen
{
CGRect frame = _rootVC.view.frame;//重新赋值
frame.origin.x = 0;
[UIView animateWithDuration:1 animations:^{
_rootVC.view.frame = frame;
self.isDisplayMenu = NO;
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//LeftViewController.h文件
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "MenuViewController.h"
/*
抽屉左边视图
*/
@interface LeftViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
/*
标题数组
*/
@property(nonatomic,strong)NSMutableArray *leftTitleArray;
/*
控制器数组
*/
@property(nonatomic,strong)NSMutableArray *viewControllersArray;
//tableview
@property(nonatomic,strong)UITableView *tableview;
@end
**//LeftViewController.m文件**
#import "LeftViewController.h"
@interface LeftViewController ()
@end
@implementation LeftViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
_tableview = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:_tableview];
_tableview.delegate = self;
_tableview.dataSource = self;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_leftTitleArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identfier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identfier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identfier];
}
cell.textLabel.text = _leftTitleArray[indexPath.row];
return cell;
}
//重点
#pragma mark 点击单元格跳转到不同的控制器
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//判断控制器数组是否存在 并且控制器数组与标题数组的个数是否一致
if (self.viewControllersArray &&(self.leftTitleArray.count == self.viewControllersArray.count)) {
//1.先取得AppDelegate
AppDelegate *app = [UIApplication sharedApplication].delegate;
//2.取得根视图控制器
MenuViewController *menu = app.menu;
//3.将打开状态设置为关闭(不设置的话,点击按钮要点击多一次才有反应)
menu.isDisplayMenu = NO;
//4.默认给控制加上一个导航控制器
UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:self.viewControllersArray[indexPath.row]];
//5.重新设置视图控制器
[menu setRootVC:navi];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//APPDeleget.h文件
#import <UIKit/UIKit.h>
#import "MenuViewController.h"
#import "ViewController.h"
#import "LeftViewController.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(nonatomic,strong)MenuViewController *menu;
@end
**//AppDelegate.m文件**
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//1.创建一个UIWidow对象
// self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// //让window对象可见
// [self.window makeKeyAndVisible];
//2.创建第一个页面的视图控制器
ViewController *readVc = [[ViewController alloc] init];
readVc.view.backgroundColor = [UIColor yellowColor];
//设置一个导航控制器
UINavigationController *firstNav = [[UINavigationController alloc] initWithRootViewController:readVc];
//为菜单按钮设置根视图控制器
_menu = [[MenuViewController alloc] initWithRootViewController:firstNav];
//创建一个左边菜单
LeftViewController *left = [[LeftViewController alloc] init];
//左边菜单标题
left.leftTitleArray = [NSMutableArray arrayWithObjects:@"首页",@"电台",@"阅读", nil];
//左边菜单控制器
FirstViewController *two = [[FirstViewController alloc] init];
SecondViewController *three = [[SecondViewController alloc] init];
left.viewControllersArray = [NSMutableArray arrayWithObjects:readVc,two,three, nil];
_menu.leftVC = left;
self.window.rootViewController = _menu;
return YES;
}