XMLeftMenuTool.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface XMLeftMenuTool : NSObject
+ (void)xl_showWithRootViewController:(UIViewController *)rootViewController leftViewController:(UIViewController *)leftViewController;
+ (void)xl_hide;
@end
XMLeftMenuTool.m
#import "XMLeftMenuTool.h"
#import "XMAnimateViewController.h"
@implementation XMLeftMenuTool
static UIWindow *_window;
+ (void)xl_showWithRootViewController:(UIViewController *)rootViewController leftViewController:(UIViewController *)leftViewController {
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor clearColor];
_window.hidden = NO;
XMAnimateViewController *viewController = [[XMAnimateViewController alloc] init];
viewController.view.backgroundColor = [UIColor clearColor];
viewController.rootViewController = rootViewController;
viewController.centerViewController = leftViewController;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
navigationController.view.backgroundColor = [UIColor clearColor];
_window.rootViewController = navigationController;
[_window addSubview:navigationController.view];
}
+ (void)xl_hide {
_window.hidden = YES;
_window.rootViewController = nil;
_window = nil;
}
@end
XMAnimateViewController.h
#import <UIKit/UIKit.h>
@interface XMAnimateViewController : UIViewController
@property (nonatomic, strong) UIViewController *rootViewController;
@property (nonatomic, strong) UIViewController *centerViewController;
@property (nonatomic, assign) BOOL xl_hideStatusBar;
@end
XMAnimateViewController.M
#import "XMAnimateViewController.h"
#import "XMLeftMenuTool.h"
static CGFloat const animationTime = 0.4;
@interface XMAnimateViewController ()
@property (nonatomic, strong) UIView *xlbackgroundView;
@property (nonatomic, strong) UIViewController *leftController;
@property (nonatomic, assign) BOOL hasShow;
@end
@implementation XMAnimateViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor blackColor];
view.frame = [UIScreen mainScreen].bounds;
view.alpha = 0;
[self.view addSubview:view];
_xlbackgroundView = view;
// 添加两个手势
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(xl_closeSideBarAction)];
[view addGestureRecognizer:tapGesture];
UIPanGestureRecognizer *panGestureRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(xl_moveViewWithGestureAction:)];
[self.view addGestureRecognizer:panGestureRec];
}
- (void)setCenterViewController:(UIViewController *)centerViewController {
[self addChildViewController:centerViewController];
CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
if ([UIScreen mainScreen].bounds.size.width > 375) {
width -= 50;
}
else if ([UIScreen mainScreen].bounds.size.width > 320) {
width = width - 25;
}
centerViewController.view.frame = CGRectMake(-width, 0, width, [UIScreen mainScreen].bounds.size.height);
[self.view addSubview:centerViewController.view];
_leftController = centerViewController;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && !self.view.window) {
self.view = nil;
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 是否隐藏 状态栏
if (!_hasShow) {
_hasShow = YES;
_xl_hideStatusBar = YES;
[UIView animateWithDuration:animationTime animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.rootViewController.navigationController.navigationBar.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 64);
}];
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self xl_showAnimation];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (void)xl_showAnimation {
self.view.userInteractionEnabled = YES;
CGFloat time = fabs(self.leftController.view.frame.origin.x / self.leftController.view.frame.size.width) * animationTime;
[UIView animateWithDuration:time animations:^{
self.leftController.view.frame = CGRectMake(0, 0, self.leftController.view.frame.size.width, [UIScreen mainScreen].bounds.size.height);
self.xlbackgroundView.alpha = 0.5;
} completion:^(BOOL finished) {
self.view.userInteractionEnabled = YES;
}];
}
- (void)xl_closeAnimation {
self.view.userInteractionEnabled = NO;
// 根据当前x,计算隐藏时间
CGFloat time = (1 - fabs(self.leftController.view.frame.origin.x / self.leftController.view.frame.size.width)) * animationTime;
[UIView animateWithDuration:time animations:^{
self.leftController.view.frame = CGRectMake(-self.leftController.view.frame.size.width, 0, self.leftController.view.frame.size.width, [UIScreen mainScreen].bounds.size.height);
self.xlbackgroundView.alpha = 0.0;
} completion:^(BOOL finished) {
// 让状态栏出现
self.xl_hideStatusBar = NO;
[UIView animateWithDuration:animationTime animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
// 隐藏个人中心
[XMLeftMenuTool xl_hide];
}];
}
- (void)xl_closeSideBarAction {
[self xl_closeAnimation];
}
- (void)xl_moveViewWithGestureAction:(UIPanGestureRecognizer *)gesture {
// 开始位置
static CGFloat start_x;
// 结束位置
static CGFloat last_x;
// 改变多少
static CGFloat duration_x;
CGPoint touchPoint = [gesture locationInView:[[UIApplication sharedApplication] keyWindow]];
// 手势开始
if (gesture.state == UIGestureRecognizerStateBegan) {
start_x = touchPoint.x;
last_x = touchPoint.x;
}
// 手势改变
if (gesture.state == UIGestureRecognizerStateChanged) {
CGFloat current_x = touchPoint.x;
duration_x = current_x - last_x;
last_x = current_x;
CGFloat leftController_x = duration_x + self.leftController.view.frame.origin.x;
// 如果控制器的x小于宽度直接返回
if (leftController_x <= -self.leftController.view.frame.size.width) {
leftController_x = -self.leftController.view.frame.size.width;
}
// 如果控制器的x大于0直接返回
if (leftController_x >= 0) {
leftController_x = 0;
}
// 计算bgView的透明度
self.xlbackgroundView.alpha = (1 + leftController_x / self.leftController.view.frame.size.width) * 0.5;
// 设置左边控制器的frame
[self.leftController.view setFrame:CGRectMake(leftController_x, 0, self.leftController.view.frame.size.width, self.leftController.view.frame.size.height)];
}
// 手势结束
if (gesture.state == UIGestureRecognizerStateEnded) {
// 结束为止超时屏幕一半
if (self.leftController.view.frame.origin.x > - self.leftController.view.frame.size.width + [UIScreen mainScreen].bounds.size.width / 2) {
[self xl_showAnimation];
} else {
[self xl_closeAnimation];
}
}
}
// MARK: - 控制状态栏
- (BOOL)prefersStatusBarHidden {
return self.xl_hideStatusBar;
}
//- (UIStatusBarStyle)preferredStatusBarStyle {
// return UIStatusBarStyleLightContent;
//}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationSlide;
}
@end