// // ICSDrawerController.m // // Created by Vito Modena // // Copyright (c) 2014 ice cream studios s.r.l. - http://icecreamstudios.com // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "ICSDrawerController.h" #import "ICSDropShadowView.h" #define kScreenSize [UIScreen mainScreen].bounds.size static const CGFloat kICSDrawerControllerDrawerDepth = 260.0f; //新增 //static const CGFloat kICSDrawerControllerDrawerDepthleft= 260.0f; static const CGFloat kICSDrawerControllerDrawerDepthright= 60.0f; static const CGFloat kICSDrawerControllerRightViewInitialOffset = 60.0f; static const CGFloat kICSDrawerControllerLeftViewInitialOffset = -60.0f; static const NSTimeInterval kICSDrawerControllerAnimationDuration = 0.5; static const NSTimeInterval kICSDrawerControllerAnimationRightDuration = 0.6; static const CGFloat kICSDrawerControllerOpeningAnimationSpringDamping = 0.9f; static const CGFloat kICSDrawerControllerOpeningAnimationSpringInitialVelocity = 0.1f; static const CGFloat kICSDrawerControllerOpeningAnimationRightSpringDamping = 0.9f; static const CGFloat kICSDrawerControllerOpeningAnimationRightSpringInitialVelocity = 0.1f; static const CGFloat kICSDrawerControllerClosingAnimationSpringDamping = 1.0f; static const CGFloat kICSDrawerControllerClosingAnimationSpringInitialVelocity = 0.5f; typedef NS_ENUM(NSUInteger, ICSDrawerControllerState) { ICSDrawerControllerStateClosed = 0, ICSDrawerControllerStateOpening, ICSDrawerControllerStateOpen, ICSDrawerControllerStateClosing, }; typedef NS_ENUM(NSUInteger ,ICSDrawerControllerLeftState) { ICSDrawerControllerStateClosedleft = 0,//默认左侧已关闭 ICSDrawerControllerStateOpeningleft, ICSDrawerControllerStateOpenleft, ICSDrawerControllerStateClosingleft, }; typedef NS_ENUM(NSUInteger ,ICSDrawerControllerRightState) { ICSDrawerControllerStateClosedright = 0,//默认右侧侧已关闭 ICSDrawerControllerStateOpeningright, ICSDrawerControllerStateOpenright, ICSDrawerControllerStateClosingright }; @interface ICSDrawerController () @property(nonatomic, strong, readwrite) UIViewController *leftViewController; @property(nonatomic, strong, readwrite) UIViewController *centerViewController; //新增 @property(nonatomic,strong,readwrite)UIViewController *rightViewController; @property(nonatomic, strong) UIView *leftView; @property(nonatomic, strong) ICSDropShadowView *centerView; //新增 @property(nonatomic, strong) UIView *rightView; @property(nonatomic, strong) UITapGestureRecognizer *tapGestureRecognizer; @property(nonatomic, strong) UIPanGestureRecognizer *panGestureRecognizer; @property(nonatomic, assign) CGPoint panGestureStartLocation; @property(nonatomic, assign) ICSDrawerControllerState drawerState; @property(nonatomic, assign) ICSDrawerControllerLeftState drawerLeftState; @property(nonatomic, assign) ICSDrawerControllerRightState drawerRightState; @end @implementation ICSDrawerController - (id)initWithLeftViewController:(UIViewController *)leftViewController centerViewController:(UIViewController *)centerViewController { NSParameterAssert(leftViewController); NSParameterAssert(centerViewController); self = [super init]; if (self) { _leftViewController = leftViewController; _centerViewController = centerViewController; if ([_leftViewController respondsToSelector:@selector(setDrawer:)]) { _leftViewController.drawer = self; } if ([_centerViewController respondsToSelector:@selector(setDrawer:)]) { _centerViewController.drawer = self; } } return self; } -(id)initWithLeftViewController:(UIViewController *)leftViewController centerViewController:(UIViewController *)centerViewController rightViewController:(UIViewController*)rightViewController { NSParameterAssert(leftViewController); NSParameterAssert(centerViewController); NSParameterAssert(rightViewController); self=[super init]; if (self) { _leftViewController=leftViewController; _centerViewController=centerViewController; _rightViewController=rightViewController; if ([_leftViewController respondsToSelector:@selector(setDrawer:)]) { _leftViewController.drawer = self; } if ([_centerViewController respondsToSelector:@selector(setDrawer:)]) { _centerViewController.drawer = self; } if ([_rightViewController respondsToSelector:@selector(setDrawer:)]) { _rightViewController.drawer=self; } } return self; } - (void)addCenterViewController { NSParameterAssert(self.centerViewController); NSParameterAssert(self.centerView); [self addChildViewController:self.centerViewController]; self.centerViewController.view.frame = self.view.bounds; [self.centerView addSubview:self.centerViewController.view]; [self.centerViewController didMoveToParentViewController:self]; } #pragma mark - Managing the view - (void)viewDidLoad { [super viewDidLoad]; self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; // Initialize left and center view containers self.leftView = [[UIView alloc] initWithFrame:self.view.bounds]; ////添加 self.rightView=[[UIView alloc]initWithFrame:self.view.bounds]; self.centerView = [[ICSDropShadowView alloc] initWithFrame:self.view.bounds]; self.leftView.autoresizingMask = self.view.autoresizingMask; self.centerView.autoresizingMask = self.view.autoresizingMask; //添加 self.rightView.autoresizingMask=self.view.autoresizingMask; // Add the center view container [self.view addSubview:self.centerView]; // Add the center view controller to the container [self addCenterViewController]; [self setupGestureRecognizers]; } #pragma mark - Configuring the view’s layout behavior - (UIViewController *)childViewControllerForStatusBarHidden { NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); //添加 NSParameterAssert(self.rightViewController); // if (self.drawerState == ICSDrawerControllerStateOpening) { // return self.leftViewController; // } // if (self.drawerLeftState==ICSDrawerControllerStateOpeningleft) { return self.leftViewController; } if (self.drawerRightState==ICSDrawerControllerStateOpeningright) { return self.rightViewController; } return self.centerViewController; } - (UIViewController *)childViewControllerForStatusBarStyle { NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); //添加 NSParameterAssert(self.rightViewController); // if (self.drawerState == ICSDrawerControllerStateOpening) { // return self.leftViewController; // } if (self.drawerState==ICSDrawerControllerStateOpeningleft) { return self.leftViewController; } if (self.drawerState==ICSDrawerControllerStateOpeningright) { return self.rightViewController; } return self.centerViewController; } #pragma mark - Gesture recognizers - (void)setupGestureRecognizers { NSParameterAssert(self.centerView); self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognized:)]; self.panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)]; self.panGestureRecognizer.maximumNumberOfTouches = 1; self.panGestureRecognizer.delegate = self; [self.centerView addGestureRecognizer:self.panGestureRecognizer]; } - (void)addClosingGestureRecognizers { NSParameterAssert(self.centerView); NSParameterAssert(self.panGestureRecognizer); [self.centerView addGestureRecognizer:self.tapGestureRecognizer]; } - (void)removeClosingGestureRecognizers { NSParameterAssert(self.centerView); NSParameterAssert(self.panGestureRecognizer); [self.centerView removeGestureRecognizer:self.tapGestureRecognizer]; } #pragma mark Tap to close the drawer - (void)tapGestureRecognized:(UITapGestureRecognizer *)tapGestureRecognizer { if (tapGestureRecognizer.state == UIGestureRecognizerStateEnded) { if (self.drawerLeftState==ICSDrawerControllerStateOpenleft && self.drawerRightState==ICSDrawerControllerStateClosedright ) { [self closeLeft]; } else if (self.drawerLeftState==ICSDrawerControllerStateClosedleft && self.drawerRightState == ICSDrawerControllerStateOpenright) { [self closeRight]; } //[self closeLeft]; } } #pragma mark Pan to open/close the drawer - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { NSParameterAssert([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]); CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:self.view]; NSLog(@"%f",velocity.x); // if (self.drawerState == ICSDrawerControllerStateClosed && velocity.x > 0.0f) { // // // return YES; // // } // // else if (self.drawerState == ICSDrawerControllerStateOpen && velocity.x < 0.0f) { // return YES; // } if (self.drawerState==ICSDrawerControllerStateClosed) { if (self.drawerLeftState==ICSDrawerControllerStateClosedleft && velocity.x > 0.0f) { return YES; } else if (self.drawerRightState==ICSDrawerControllerStateClosedright && velocity.x < 0.0f){ return YES; } } else if (self.drawerState==ICSDrawerControllerStateOpen){ if (self.drawerLeftState==ICSDrawerControllerStateOpenleft && velocity.x < 0.0f) { return YES; } else if (self.drawerRightState==ICSDrawerControllerStateOpenright &&velocity.x > 0.0f){ return YES; } } return NO; } - (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer { NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); UIGestureRecognizerState state = panGestureRecognizer.state; CGPoint location = [panGestureRecognizer locationInView:self.view]; CGPoint velocity = [panGestureRecognizer velocityInView:self.view]; switch (state) { case UIGestureRecognizerStateBegan: self.panGestureStartLocation = location; if (self.drawerState == ICSDrawerControllerStateClosed) { if (self.drawerLeftState == ICSDrawerControllerStateClosedleft && velocity.x > 0.0f){ // Keep track that the left drawer is opening self.drawerLeftState = ICSDrawerControllerStateOpeningleft; //[self willOpen]; [self willOpenLeft]; } else if (self.drawerRightState == ICSDrawerControllerStateClosedright && velocity.x < 0.0f){ // Keep track that the right drawer is opening self.drawerRightState = ICSDrawerControllerStateOpeningright; //[self willOpen]; [self willOpenRight]; } // [self willOpen]; } else { if (self.drawerLeftState == ICSDrawerControllerStateOpenleft) { [self closeLeft]; } else if (self.drawerRightState == ICSDrawerControllerStateOpenright){ [self closeRight]; } // [self willClose]; } break; case UIGestureRecognizerStateChanged: { CGFloat delta = 0.0f; CGFloat deltadata = 0.0f; if (self.drawerState == ICSDrawerControllerStateOpening) { if (self.drawerLeftState == ICSDrawerControllerStateOpeningleft && velocity.x > 0.0f) { delta = location.x - self.panGestureStartLocation.x; } else if (self.drawerRightState == ICSDrawerControllerStateOpeningright && velocity.x < 0.0f){ deltadata = self.panGestureStartLocation.x-location.x; // NSLog(@" deltadata%f", deltadata); } // delta = location.x - self.panGestureStartLocation.x; } else if (self.drawerState == ICSDrawerControllerStateClosing) { if (self.drawerLeftState == ICSDrawerControllerStateClosingleft && velocity.x < 0.0f) { delta = kICSDrawerControllerDrawerDepth - (self.panGestureStartLocation.x - location.x); } else if (self.drawerRightState == ICSDrawerControllerStateClosingright && velocity.x > 0.0f) { deltadata = location.x- self.panGestureStartLocation.x; } // delta = kICSDrawerControllerDrawerDepth - (self.panGestureStartLocation.x - location.x); } CGRect l = self.leftView.frame; CGRect c = self.centerView.frame; CGRect r = self.rightView.frame; if (self.drawerLeftState == ICSDrawerControllerStateOpeningleft|self.drawerLeftState == ICSDrawerControllerStateClosingleft) { if (delta > kScreenSize.width - 60) { l.origin.x = 0.0f; c.origin.x = kScreenSize.width - 60; } else if (delta < 0.0f) { l.origin.x = kICSDrawerControllerLeftViewInitialOffset; c.origin.x = 0.0f; } else { // While the centerView can move up to kICSDrawerControllerDrawerDepth points, to achieve a parallax effect // the leftView has move no more than kICSDrawerControllerLeftViewInitialOffset points l.origin.x = kICSDrawerControllerLeftViewInitialOffset - (delta * kICSDrawerControllerLeftViewInitialOffset) / (kScreenSize.width - 60); c.origin.x = delta; } } else if (self.drawerRightState == ICSDrawerControllerStateOpeningright|self.drawerRightState == ICSDrawerControllerStateClosingright){ if (deltadata > kScreenSize.width - 60) { r.origin.x = kICSDrawerControllerDrawerDepthright; c.origin.x = -(kScreenSize.width - 60); }else if (deltadata < 0.0f) { r.origin.x = kScreenSize.width - 60; c.origin.x = 0.0f; }else{ r.origin.x = self.rightView.bounds.size.width-deltadata; c.origin.x = -deltadata; } } self.leftView.frame = l; self.centerView.frame = c; self.rightView.frame = r; break; } case UIGestureRecognizerStateEnded: if (self.drawerState == ICSDrawerControllerStateOpening) { if (self.drawerLeftState == ICSDrawerControllerStateOpeningleft) { CGFloat centerViewLocation = self.centerView.frame.origin.x; if (centerViewLocation == kScreenSize.width - 60) { // Open the drawer without animation, as it has already being dragged in its final position [self setNeedsStatusBarAppearanceUpdate]; [self didOpenLeft]; } else if (centerViewLocation > self.view.bounds.size.width / 3 && velocity.x > 0.0f) { // Animate the drawer opening [self animateOpeningLeft]; } else { // Animate the drawer closing, as the opening gesture hasn't been completed or it has // been reverted by the user [self didOpenLeft]; [self willCloseLeft]; [self animateClosingLeft]; } } else if (self.drawerRightState == ICSDrawerControllerStateOpeningright){ CGFloat centerViewLocation = self.centerView.frame.origin.x; if (centerViewLocation == -(kScreenSize.width-60)) { // Open the drawer without animation, as it has already being dragged in its final position [self setNeedsStatusBarAppearanceUpdate]; [self didOpenRight]; } else if (-centerViewLocation > self.view.bounds.size.width / 3 && velocity.x < 0.0f) { // Animate the drawer opening [self animateOpeningRight]; } else { // Animate the drawer closing, as the opening gesture hasn't been completed or it has // been reverted by the user [self didOpenRight]; [self willCloseRight]; [self animateClosingRight]; } } }else if (self.drawerState == ICSDrawerControllerStateClosing) { if (self.drawerLeftState == ICSDrawerControllerStateClosingleft) { CGFloat centerViewLocation = self.centerView.frame.origin.x; if (centerViewLocation == 0.0f) { // Close the drawer without animation, as it has already being dragged in its final position [self setNeedsStatusBarAppearanceUpdate]; [self didCloseLeft]; } else if (centerViewLocation < (2 * self.view.bounds.size.width) / 3 && velocity.x < 0.0f) { // Animate the drawer closing [self animateClosingLeft]; } else { // Animate the drawer opening, as the opening gesture hasn't been completed or it has // been reverted by the user [self didCloseLeft]; // Here we save the current position for the leftView since // we want the opening animation to start from the current position // and not the one that is set in 'willOpen' CGRect l = self.leftView.frame; [self willOpenLeft]; self.leftView.frame = l; [self animateOpeningLeft]; } } else if (self.drawerRightState == ICSDrawerControllerStateClosingright){ } } break; default: break; } } #pragma mark - Animations #pragma mark Opening animation - (void)animateOpening { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); // Calculate the final frames for the container views CGRect leftViewFinalFrame = self.view.bounds; CGRect centerViewFinalFrame = self.view.bounds; centerViewFinalFrame.origin.x = kICSDrawerControllerDrawerDepth; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration delay:0 usingSpringWithDamping:kICSDrawerControllerOpeningAnimationSpringDamping initialSpringVelocity:kICSDrawerControllerOpeningAnimationSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.leftView.frame = leftViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished) { [self didOpen]; }]; } -(void)animateOpeningLeft { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); // Calculate the final frames for the container views CGRect leftViewFinalFrame = self.view.bounds; CGRect centerViewFinalFrame = self.view.bounds; // centerViewFinalFrame.origin.x = kICSDrawerControllerDrawerDepth; centerViewFinalFrame.origin.x = kScreenSize.width-60; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration delay:0 usingSpringWithDamping:kICSDrawerControllerOpeningAnimationSpringDamping initialSpringVelocity:kICSDrawerControllerOpeningAnimationSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.leftView.frame = leftViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished){ [self didOpenLeft]; }]; } -(void)animateOpeningRight{ NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.rightView); NSParameterAssert(self.centerView); // Calculate the final frames for the container views CGRect rightViewFinalFrame = self.view.bounds; CGRect centerViewFinalFrame = self.view.bounds; centerViewFinalFrame.origin.x = 60 - kScreenSize.width; rightViewFinalFrame.origin.x=kICSDrawerControllerRightViewInitialOffset; [UIView animateWithDuration:kICSDrawerControllerAnimationRightDuration delay:0 usingSpringWithDamping:kICSDrawerControllerOpeningAnimationRightSpringDamping initialSpringVelocity:kICSDrawerControllerOpeningAnimationRightSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.rightView.frame = rightViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished){ [self didOpenRight]; }]; } #pragma mark Closing animation - (void)animateClosing { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); // Calculate final frames for the container views CGRect leftViewFinalFrame = self.leftView.frame; leftViewFinalFrame.origin.x = kICSDrawerControllerLeftViewInitialOffset; CGRect centerViewFinalFrame = self.view.bounds; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration delay:0 usingSpringWithDamping:kICSDrawerControllerClosingAnimationSpringDamping initialSpringVelocity:kICSDrawerControllerClosingAnimationSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.leftView.frame = leftViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished) { [self didClose]; }]; } -(void)animateClosingLeft { // NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); // Calculate final frames for the container views CGRect leftViewFinalFrame = self.leftView.frame; leftViewFinalFrame.origin.x = kICSDrawerControllerLeftViewInitialOffset; CGRect centerViewFinalFrame = self.view.bounds; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration delay:0 usingSpringWithDamping:kICSDrawerControllerClosingAnimationSpringDamping initialSpringVelocity:kICSDrawerControllerClosingAnimationSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.leftView.frame = leftViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished) { [self didCloseLeft]; }]; } -(void)animateClosingRight{ //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.rightView); NSParameterAssert(self.centerView); // Calculate final frames for the container views CGRect rightViewFinalFrame = self.rightView.frame; rightViewFinalFrame.origin.x = self.rightView.frame.size.width; CGRect centerViewFinalFrame = self.view.bounds; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration delay:0 usingSpringWithDamping:kICSDrawerControllerClosingAnimationSpringDamping initialSpringVelocity:kICSDrawerControllerClosingAnimationSpringInitialVelocity options:UIViewAnimationOptionCurveLinear animations:^{ self.centerView.frame = centerViewFinalFrame; self.rightView.frame = rightViewFinalFrame; [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished) { [self didColseRight]; }]; } #pragma mark - Opening the drawer - (void)open { NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); [self willOpen]; [self animateOpening]; } - (void)willOpen { NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); //NSParameterAssert(self.rightView); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // NSParameterAssert(self.rightViewController); // Keep track that the drawer is opening self.drawerState = ICSDrawerControllerStateOpening; //NSLog(@"ICSDrawerControllerStateOpening"); // Position the left view CGRect f = self.view.bounds; f.origin.x = kICSDrawerControllerLeftViewInitialOffset; NSParameterAssert(f.origin.x < 0.0f); self.leftView.frame = f; // Start adding the left view controller to the container [self addChildViewController:self.leftViewController]; self.leftViewController.view.frame = self.leftView.bounds; [self.leftView addSubview:self.leftViewController.view]; // Add the left view to the view hierarchy [self.view insertSubview:self.leftView belowSubview:self.centerView]; // Notify the child view controllers that the drawer is about to open if ([self.leftViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.leftViewController drawerControllerWillOpen:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.centerViewController drawerControllerWillOpen:self]; } } - (void)didOpen { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Complete adding the left controller to the container [self.leftViewController didMoveToParentViewController:self]; [self addClosingGestureRecognizers]; // Keep track that the drawer is open self.drawerState = ICSDrawerControllerStateOpen; // Notify the child view controllers that the drawer is open if ([self.leftViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.leftViewController drawerControllerDidOpen:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.centerViewController drawerControllerDidOpen:self]; } } #pragma mark - Closing the drawer - (void)close { // NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); [self willClose]; [self animateClosing]; } - (void)willClose { // NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Start removing the left controller from the container [self.leftViewController willMoveToParentViewController:nil]; // Keep track that the drawer is closing self.drawerState = ICSDrawerControllerStateClosing; // Notify the child view controllers that the drawer is about to close if ([self.leftViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.leftViewController drawerControllerWillClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.centerViewController drawerControllerWillClose:self]; } } - (void)didClose { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Complete removing the left view controller from the container [self.leftViewController.view removeFromSuperview]; [self.leftViewController removeFromParentViewController]; // Remove the left view from the view hierarchy [self.leftView removeFromSuperview]; [self removeClosingGestureRecognizers]; // Keep track that the drawer is closed self.drawerState = ICSDrawerControllerStateClosed; // Notify the child view controllers that the drawer is closed if ([self.leftViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.leftViewController drawerControllerDidClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.centerViewController drawerControllerDidClose:self]; } } -(void)openLeft { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); //NSParameterAssert(self.drawerLeftState == ICSDrawerControllerStateClosedleft); if (self.drawerLeftState == ICSDrawerControllerStateClosedleft && self.drawerRightState == ICSDrawerControllerStateClosedright) { [self willOpenLeft]; [self animateOpeningLeft]; }else if(self.drawerLeftState == ICSDrawerControllerStateOpenleft && self.drawerRightState == ICSDrawerControllerStateClosedright){ [self willCloseLeft]; [self animateClosingLeft]; }else{ return; } } -(void)willOpenLeft { NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Keep track that the drawer is opening self.drawerState = ICSDrawerControllerStateOpening; // NSLog(@"ICSDrawerControllerStateOpening"); // Position the left view CGRect f = self.view.bounds; f.origin.x = kICSDrawerControllerLeftViewInitialOffset; NSParameterAssert(f.origin.x < 0.0f); self.leftView.frame = f; // Start adding the left view controller to the container [self addChildViewController:self.leftViewController]; self.leftViewController.view.frame = self.leftView.bounds; [self.leftView addSubview:self.leftViewController.view]; // Add the left view to the view hierarchy [self.view insertSubview:self.leftView belowSubview:self.centerView]; // Notify the child view controllers that the drawer is about to open if ([self.leftViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.leftViewController drawerControllerWillOpen:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.centerViewController drawerControllerWillOpen:self]; } } - (void)didOpenLeft { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Complete adding the left controller to the container [self.leftViewController didMoveToParentViewController:self]; [self addClosingGestureRecognizers]; // Keep track that the drawer is open self.drawerState = ICSDrawerControllerStateOpen; self.drawerLeftState = ICSDrawerControllerStateOpenleft; self.drawerRightState = ICSDrawerControllerStateClosedright; // Notify the child view controllers that the drawer is open if ([self.leftViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.leftViewController drawerControllerDidOpen:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.centerViewController drawerControllerDidOpen:self]; } // if ([self.rightViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { // // [self.leftViewController drawerControllerDidOpen:self]; // } } - (void)closeLeft { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); [self willCloseLeft]; [self animateClosingLeft]; } -(void)willCloseLeft { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Start removing the left controller from the container [self.leftViewController willMoveToParentViewController:nil]; // Keep track that the drawer is closing self.drawerState = ICSDrawerControllerStateClosing; // Notify the child view controllers that the drawer is about to close if ([self.leftViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.leftViewController drawerControllerWillClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.centerViewController drawerControllerWillClose:self]; } } - (void)didCloseLeft { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.leftView); NSParameterAssert(self.centerView); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Complete removing the left view controller from the container [self.leftViewController.view removeFromSuperview]; [self.leftViewController removeFromParentViewController]; // Remove the left view from the view hierarchy [self.leftView removeFromSuperview]; [self removeClosingGestureRecognizers]; // Keep track that the drawer is closed self.drawerState = ICSDrawerControllerStateClosed; self.drawerLeftState = ICSDrawerControllerStateClosedleft; self.drawerRightState = ICSDrawerControllerStateClosedright; // Notify the child view controllers that the drawer is closed if ([self.leftViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.leftViewController drawerControllerDidClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.centerViewController drawerControllerDidClose:self]; } } -(void)openRight { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); //NSParameterAssert(self.drawerLeftState == ICSDrawerControllerStateClosedleft); if (self.drawerRightState == ICSDrawerControllerStateClosedright && self.drawerLeftState == ICSDrawerControllerStateClosedleft) { [self willOpenRight]; [self animateOpeningRight]; }else if (self.drawerRightState == ICSDrawerControllerStateOpenright && self.drawerLeftState == ICSDrawerControllerStateClosedleft){ [self willCloseRight]; [self animateClosingRight]; } else{ return; } } -(void)willOpenRight { NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosed); NSParameterAssert(self.rightView); NSParameterAssert(self.centerView); NSParameterAssert(self.rightViewController); NSParameterAssert(self.centerViewController); // Keep track that the drawer is opening self.drawerState = ICSDrawerControllerStateOpening; self.drawerRightState = ICSDrawerControllerStateOpeningright; //NSLog(@"ICSDrawerControllerStateOpening"); // Position the right view CGRect f = self.view.bounds; f.origin.x = kICSDrawerControllerRightViewInitialOffset; NSParameterAssert(f.origin.x > 0.0f); self.rightView.frame = f; // Start adding the right view controller to the container [self addChildViewController:self.rightViewController]; self.rightViewController.view.frame = self.rightView.bounds; [self.rightView addSubview:self.rightViewController.view]; // Add the right view to the view hierarchy [self.view insertSubview:self.rightView belowSubview:self.centerView]; // Notify the child view controllers that the drawer is about to open if ([self.rightViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.rightViewController drawerControllerWillOpen:self]; } if ([self.rightViewController respondsToSelector:@selector(drawerControllerWillOpen:)]) { [self.rightViewController drawerControllerWillOpen:self]; } } -(void)didOpenRight { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening); NSParameterAssert(self.leftViewController); NSParameterAssert(self.centerViewController); // Complete adding the right controller to the container [self.rightViewController didMoveToParentViewController:self]; [self addClosingGestureRecognizers]; // Keep track that the drawer is open self.drawerState = ICSDrawerControllerStateOpen; self.drawerLeftState = ICSDrawerControllerStateClosedleft; self.drawerRightState = ICSDrawerControllerStateOpenright; // Notify the child view controllers that the drawer is open if ([self.rightViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.rightViewController drawerControllerDidOpen:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidOpen:)]) { [self.centerViewController drawerControllerDidOpen:self]; } } -(void)closeRight { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); [self willCloseRight]; [self animateClosingRight]; } -(void)willCloseRight { //NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpen); NSParameterAssert(self.rightViewController); NSParameterAssert(self.centerViewController); // Start removing the right controller from the container [self.rightViewController willMoveToParentViewController:nil]; // Keep track that the drawer is closing self.drawerState = ICSDrawerControllerStateClosing; // Notify the child view controllers that the drawer is about to close if ([self.rightViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.rightViewController drawerControllerWillClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerWillClose:)]) { [self.centerViewController drawerControllerWillClose:self]; } } -(void)didColseRight { // NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing); NSParameterAssert(self.rightView); NSParameterAssert(self.centerView); NSParameterAssert(self.rightViewController); NSParameterAssert(self.centerViewController); // Complete removing the right view controller from the container [self.rightViewController.view removeFromSuperview]; [self.rightViewController removeFromParentViewController]; // Remove the right view from the view hierarchy [self.rightView removeFromSuperview]; [self removeClosingGestureRecognizers]; // Keep track that the drawer is closed self.drawerState = ICSDrawerControllerStateClosed; self.drawerRightState = ICSDrawerControllerStateClosedright; // Notify the child view controllers that the drawer is closed if ([self.rightViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.rightViewController drawerControllerDidClose:self]; } if ([self.centerViewController respondsToSelector:@selector(drawerControllerDidClose:)]) { [self.centerViewController drawerControllerDidClose:self]; } } #pragma mark - Reloading/Replacing the center view controller - (void)reloadCenterViewControllerUsingBlock:(void (^)(void))reloadBlock { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpenleft); NSParameterAssert(self.centerViewController); [self willClose]; CGRect f = self.centerView.frame; f.origin.x = self.view.bounds.size.width; [UIView animateWithDuration: kICSDrawerControllerAnimationDuration / 2 animations:^{ self.centerView.frame = f; } completion:^(BOOL finished) { // The center view controller is now out of sight if (reloadBlock) { reloadBlock(); } // Finally, close the drawer [self animateClosing]; }]; } - (void)replaceCenterViewControllerWithViewController:(UIViewController *)viewController { NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpenleft); NSParameterAssert(viewController); NSParameterAssert(self.centerView); NSParameterAssert(self.centerViewController); [self willClose]; CGRect f = self.centerView.frame; f.origin.x = self.view.bounds.size.width; [self.centerViewController willMoveToParentViewController:nil]; [UIView animateWithDuration: kICSDrawerControllerAnimationDuration / 2 animations:^{ self.centerView.frame = f; } completion:^(BOOL finished) { // The center view controller is now out of sight // Remove the current center view controller from the container if ([self.centerViewController respondsToSelector:@selector(setDrawer:)]) { self.centerViewController.drawer = nil; } [self.centerViewController.view removeFromSuperview]; [self.centerViewController removeFromParentViewController]; // Set the new center view controller self.centerViewController = viewController; if ([self.centerViewController respondsToSelector:@selector(setDrawer:)]) { self.centerViewController.drawer = self; } // Add the new center view controller to the container [self addCenterViewController]; // Finally, close the drawer [self animateClosing]; }]; } -(void)viewWillAppear:(BOOL)animated{ self.navigationController.navigationBarHidden=YES; } @end