Merge remote-tracking branch 'origin/custom_animation'

* origin/custom_animation:
  - Cleanup - Fixed typo in property name renamed “leftbarButtonItem” to “leftBarButtonItem”
  - Fixed a bug where menu animation does not get completed when switching to another view controller because that viewController is not presenting the menu (delegate return NO or not implemented)
  - Some cleanup - Structured menu for a better presentation of slide menu features
  - Implemented clear for slide animation - Fixed an issue with scale animation
  - Separated all reveal animations from SlideNavigationController - Allowing a custom animation to be passed to slide menu and used for menu reveal animation
  - Added scale animation
This commit is contained in:
Aryan Ghassemi 2014-01-27 20:18:21 -08:00
commit 8d331af74e
17 changed files with 719 additions and 184 deletions

View File

@ -24,6 +24,11 @@
15371F141728E3B400A508F4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 15371F121728E3B400A508F4 /* InfoPlist.strings */; };
15371F171728E3B400A508F4 /* SlideMenuTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 15371F161728E3B400A508F4 /* SlideMenuTests.m */; };
15371F281728E44E00A508F4 /* SlideNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 15371F271728E44E00A508F4 /* SlideNavigationController.m */; };
15C9AC111895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.m in Sources */ = {isa = PBXBuildFile; fileRef = 15C9AC101895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.m */; };
15C9AC141895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.m in Sources */ = {isa = PBXBuildFile; fileRef = 15C9AC131895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.m */; };
15C9AC171895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.m in Sources */ = {isa = PBXBuildFile; fileRef = 15C9AC161895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.m */; };
15C9AC1A1895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.m in Sources */ = {isa = PBXBuildFile; fileRef = 15C9AC191895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.m */; };
15C9AC1D1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.m in Sources */ = {isa = PBXBuildFile; fileRef = 15C9AC1C1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.m */; };
15CBD67C172A15F900F0C53E /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 15CBD677172A15F900F0C53E /* HomeViewController.m */; };
15CBD67D172A15F900F0C53E /* MenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 15CBD679172A15F900F0C53E /* MenuViewController.m */; };
15CBD67E172A15F900F0C53E /* ProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 15CBD67B172A15F900F0C53E /* ProfileViewController.m */; };
@ -68,6 +73,17 @@
15371F161728E3B400A508F4 /* SlideMenuTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SlideMenuTests.m; sourceTree = "<group>"; };
15371F261728E44E00A508F4 /* SlideNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationController.h; sourceTree = "<group>"; };
15371F271728E44E00A508F4 /* SlideNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationController.m; sourceTree = "<group>"; };
15C9AC0F1895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimatorSlide.h; sourceTree = "<group>"; };
15C9AC101895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationContorllerAnimatorSlide.m; sourceTree = "<group>"; };
15C9AC121895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimatorFade.h; sourceTree = "<group>"; };
15C9AC131895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationContorllerAnimatorFade.m; sourceTree = "<group>"; };
15C9AC151895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimatorSlideAndFade.h; sourceTree = "<group>"; };
15C9AC161895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationContorllerAnimatorSlideAndFade.m; sourceTree = "<group>"; };
15C9AC181895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimatorScale.h; sourceTree = "<group>"; };
15C9AC191895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationContorllerAnimatorScale.m; sourceTree = "<group>"; };
15C9AC1B1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimatorScaleAndFade.h; sourceTree = "<group>"; };
15C9AC1C1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlideNavigationContorllerAnimatorScaleAndFade.m; sourceTree = "<group>"; };
15C9AC1E1895A832006E6F27 /* SlideNavigationContorllerAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlideNavigationContorllerAnimator.h; sourceTree = "<group>"; };
15CBD676172A15F900F0C53E /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = "<group>"; };
15CBD677172A15F900F0C53E /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = "<group>"; };
15CBD678172A15F900F0C53E /* MenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuViewController.h; sourceTree = "<group>"; };
@ -189,6 +205,7 @@
15371F241728E43600A508F4 /* Source */ = {
isa = PBXGroup;
children = (
15C9AC0E1895A79A006E6F27 /* Animations */,
15CBD681172A209500F0C53E /* Assets */,
15371F261728E44E00A508F4 /* SlideNavigationController.h */,
15371F271728E44E00A508F4 /* SlideNavigationController.m */,
@ -196,6 +213,24 @@
path = Source;
sourceTree = "<group>";
};
15C9AC0E1895A79A006E6F27 /* Animations */ = {
isa = PBXGroup;
children = (
15C9AC0F1895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.h */,
15C9AC101895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.m */,
15C9AC121895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.h */,
15C9AC131895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.m */,
15C9AC151895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.h */,
15C9AC161895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.m */,
15C9AC181895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.h */,
15C9AC191895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.m */,
15C9AC1B1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.h */,
15C9AC1C1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.m */,
15C9AC1E1895A832006E6F27 /* SlideNavigationContorllerAnimator.h */,
);
path = Animations;
sourceTree = "<group>";
};
15CBD675172A15F900F0C53E /* Helper Classes */ = {
isa = PBXGroup;
children = (
@ -335,12 +370,17 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
15C9AC1D1895A81D006E6F27 /* SlideNavigationContorllerAnimatorScaleAndFade.m in Sources */,
15C9AC171895A7E7006E6F27 /* SlideNavigationContorllerAnimatorSlideAndFade.m in Sources */,
15371EEF1728E3B400A508F4 /* main.m in Sources */,
15371EF31728E3B400A508F4 /* AppDelegate.m in Sources */,
15C9AC141895A7D7006E6F27 /* SlideNavigationContorllerAnimatorFade.m in Sources */,
15371F281728E44E00A508F4 /* SlideNavigationController.m in Sources */,
15C9AC111895A7BF006E6F27 /* SlideNavigationContorllerAnimatorSlide.m in Sources */,
15CBD67C172A15F900F0C53E /* HomeViewController.m in Sources */,
997929E2187336AA00716C77 /* FriendsViewController.m in Sources */,
15CBD67D172A15F900F0C53E /* MenuViewController.m in Sources */,
15C9AC1A1895A80E006E6F27 /* SlideNavigationContorllerAnimatorScale.m in Sources */,
15CBD67E172A15F900F0C53E /* ProfileViewController.m in Sources */,
15CBD689172A22B700F0C53E /* ProfileDetailViewController.m in Sources */,
);

View File

@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>
#import "SlideNavigationController.h"
@interface MenuViewController : UIViewController <UITableViewDelegate>
@interface MenuViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSString *cellIdentifier;

View File

@ -7,42 +7,85 @@
//
#import "MenuViewController.h"
#import "SlideNavigationContorllerAnimatorFade.h"
#import "SlideNavigationContorllerAnimatorSlide.h"
#import "SlideNavigationContorllerAnimatorScale.h"
#import "SlideNavigationContorllerAnimatorScaleAndFade.h"
#import "SlideNavigationContorllerAnimatorSlideAndFade.h"
@implementation MenuViewController
@synthesize cellIdentifier;
#pragma mark - UITableView Delegate & Datasrouce -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 15;
return (section == 0) ? 4 : 6;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return (section == 0) ? @"Navigation" : @"Menu Animation";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier];
switch (indexPath.row)
if (indexPath.section == 0)
{
case 0:
cell.textLabel.text = @"Home";
break;
case 1:
cell.textLabel.text = @"Profile";
break;
case 2:
cell.textLabel.text = @"Friends";
break;
case 3:
cell.textLabel.text = @"Sign Out";
break;
default:
cell.textLabel.text = @"Random Cell";
break;
switch (indexPath.row)
{
case 0:
cell.textLabel.text = @"Home";
break;
case 1:
cell.textLabel.text = @"Profile";
break;
case 2:
cell.textLabel.text = @"Friends";
break;
case 3:
cell.textLabel.text = @"Sign Out";
break;
}
}
else
{
switch (indexPath.row)
{
case 0:
cell.textLabel.text = @"No Animation";
break;
case 1:
cell.textLabel.text = @"Slide Animation";
break;
case 2:
cell.textLabel.text = @"Fade Animation";
break;
case 3:
cell.textLabel.text = @"Slide And Fade Animation";
break;
case 4:
cell.textLabel.text = @"Scale Animation";
break;
case 5:
cell.textLabel.text = @"Scale And Fade Animation";
break;
}
}
return cell;
@ -53,32 +96,70 @@
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone"
bundle: nil];
UIViewController *vc ;
switch (indexPath.row)
if (indexPath.section == 0)
{
case 0:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"HomeViewController"];
break;
case 1:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"ProfileViewController"];
break;
case 2:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"FriendsViewController"];
break;
case 3:
[[SlideNavigationController sharedInstance] popToRootViewControllerAnimated:YES];
return;
break;
default:
return;
UIViewController *vc ;
switch (indexPath.row)
{
case 0:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"HomeViewController"];
break;
case 1:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"ProfileViewController"];
break;
case 2:
vc = [mainStoryboard instantiateViewControllerWithIdentifier: @"FriendsViewController"];
break;
case 3:
[[SlideNavigationController sharedInstance] popToRootViewControllerAnimated:YES];
return;
break;
}
[[SlideNavigationController sharedInstance] switchToViewController:vc withCompletion:nil];
}
else
{
id <SlideNavigationContorllerAnimator> revealAnimator;
switch (indexPath.row)
{
case 0:
revealAnimator = nil;
break;
case 1:
revealAnimator = [[SlideNavigationContorllerAnimatorSlide alloc] init];
break;
case 2:
revealAnimator = [[SlideNavigationContorllerAnimatorFade alloc] init];
break;
case 3:
revealAnimator = [[SlideNavigationContorllerAnimatorSlideAndFade alloc] initWithMaximumFadeAlpha:.7 fadeColor:[UIColor purpleColor] andSlideMovement:100];
break;
case 4:
revealAnimator = [[SlideNavigationContorllerAnimatorScale alloc] init];
break;
case 5:
revealAnimator = [[SlideNavigationContorllerAnimatorScaleAndFade alloc] initWithMaximumFadeAlpha:.6 fadeColor:[UIColor blueColor] andMinimumScale:.7];
break;
default:
return;
}
[[SlideNavigationController sharedInstance] closeMenuWithCompletion:^{
[SlideNavigationController sharedInstance].menuRevealAnimator = revealAnimator;
}];
}
[[SlideNavigationController sharedInstance] switchToViewController:vc withCompletion:nil];
}
@end

View File

@ -0,0 +1,25 @@
//
// SlideNavigationContorllerAnimation.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationController.h"
@protocol SlideNavigationContorllerAnimator <NSObject>
// Initial state of the view before animation starts
// This gets called right before the menu is about to reveal
- (void)prepareMenuForAnimation:(Menu)menu;
// Animate the view based on the progress (progress is between 0 and 1)
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress;
// Gets called ff for any the instance of animator is being change
// You should make any cleanup that is needed
- (void)clear;
@end

View File

@ -0,0 +1,19 @@
//
// SlideNavigationContorllerAnimationFade.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationContorllerAnimatorFade : NSObject <SlideNavigationContorllerAnimator>
@property (nonatomic, assign) CGFloat maximumFadeAlpha;
@property (nonatomic, strong) UIColor *fadeColor;
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha andFadeColor:(UIColor *)fadeColor;
@end

View File

@ -0,0 +1,70 @@
//
// SlideNavigationContorllerAnimationFade.m
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import "SlideNavigationContorllerAnimatorFade.h"
@interface SlideNavigationContorllerAnimatorFade()
@property (nonatomic, strong) UIView *fadeAnimationView;
@end
@implementation SlideNavigationContorllerAnimatorFade
#pragma mark - Initialization -
- (id)init
{
if (self = [self initWithMaximumFadeAlpha:.8 andFadeColor:[UIColor blackColor]])
{
}
return self;
}
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha andFadeColor:(UIColor *)fadeColor
{
if (self = [super init])
{
self.maximumFadeAlpha = maximumFadeAlpha;
self.fadeColor = fadeColor;
self.fadeAnimationView = [[UIView alloc] init];
self.fadeAnimationView.backgroundColor = self.fadeColor;
}
return self;
}
#pragma mark - SlideNavigationContorllerAnimation Methods -
- (void)prepareMenuForAnimation:(Menu)menu
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
self.fadeAnimationView.alpha = self.maximumFadeAlpha;
self.fadeAnimationView.frame = menuViewController.view.bounds;
}
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
self.fadeAnimationView.frame = menuViewController.view.bounds;
[menuViewController.view addSubview:self.fadeAnimationView];
self.fadeAnimationView.alpha = self.maximumFadeAlpha - (self.maximumFadeAlpha *progress);
}
- (void)clear
{
[self.fadeAnimationView removeFromSuperview];
}
@end

View File

@ -0,0 +1,18 @@
//
// SlideNavigationContorllerAnimationScale.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationContorllerAnimatorScale : NSObject <SlideNavigationContorllerAnimator>
@property (nonatomic, assign) CGFloat minimumScale;
- (id)initWithMinimumScale:(CGFloat)minimumScale;
@end

View File

@ -0,0 +1,61 @@
//
// SlideNavigationContorllerAnimationScale.m
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import "SlideNavigationContorllerAnimatorScale.h"
@implementation SlideNavigationContorllerAnimatorScale
#pragma mark - Initialization -
- (id)init
{
if (self = [self initWithMinimumScale:.9])
{
}
return self;
}
- (id)initWithMinimumScale:(CGFloat)minimumScale
{
if (self = [super init])
{
self.minimumScale = minimumScale;
}
return self;
}
#pragma mark - SlideNavigationContorllerAnimation Methods -
- (void)prepareMenuForAnimation:(Menu)menu
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
menuViewController.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, self.minimumScale, self.minimumScale);
}
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
CGFloat scale = MIN(1, (1-self.minimumScale) *progress + self.minimumScale);
menuViewController.view.transform = CGAffineTransformScale([SlideNavigationController sharedInstance].view.transform, scale, scale);
}
- (void)clear
{
[SlideNavigationController sharedInstance].leftMenu.view.transform = CGAffineTransformScale([SlideNavigationController sharedInstance].view.transform, 1, 1);
[SlideNavigationController sharedInstance].rightMenu.view.transform = CGAffineTransformScale([SlideNavigationController sharedInstance].view.transform, 1, 1);
}
@end

View File

@ -0,0 +1,16 @@
//
// SlideNavigationContorllerAnimationScaleAndFade.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationContorllerAnimatorScaleAndFade : NSObject <SlideNavigationContorllerAnimator>
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha fadeColor:(UIColor *)fadeColor andMinimumScale:(CGFloat)minimumScale;
@end

View File

@ -0,0 +1,62 @@
//
// SlideNavigationContorllerAnimationScaleAndFade.m
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import "SlideNavigationContorllerAnimatorScaleAndFade.h"
#import "SlideNavigationContorllerAnimatorFade.h"
#import "SlideNavigationContorllerAnimatorScale.h"
@interface SlideNavigationContorllerAnimatorScaleAndFade()
@property (nonatomic, strong) SlideNavigationContorllerAnimatorFade *fadeAnimation;
@property (nonatomic, strong) SlideNavigationContorllerAnimatorScale *scaleAnimation;
@end
@implementation SlideNavigationContorllerAnimatorScaleAndFade
#pragma mark - Initialization -
- (id)init
{
if (self = [self initWithMaximumFadeAlpha:.8 fadeColor:[UIColor blackColor] andMinimumScale:.8])
{
}
return self;
}
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha fadeColor:(UIColor *)fadeColor andMinimumScale:(CGFloat)minimumScale
{
if (self = [super init])
{
self.fadeAnimation = [[SlideNavigationContorllerAnimatorFade alloc] initWithMaximumFadeAlpha:maximumFadeAlpha andFadeColor:fadeColor];
self.scaleAnimation = [[SlideNavigationContorllerAnimatorScale alloc] initWithMinimumScale:minimumScale];
}
return self;
}
#pragma mark - SlideNavigationContorllerAnimation Methods -
- (void)prepareMenuForAnimation:(Menu)menu
{
[self.fadeAnimation prepareMenuForAnimation:menu];
[self.scaleAnimation prepareMenuForAnimation:menu];
}
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress
{
[self.fadeAnimation animateMenu:menu withProgress:progress];
[self.scaleAnimation animateMenu:menu withProgress:progress];
}
- (void)clear
{
[self.fadeAnimation clear];
[self.scaleAnimation clear];
}
@end

View File

@ -0,0 +1,18 @@
//
// SlideNavigationContorllerAnimationSlide.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationContorllerAnimatorSlide : NSObject <SlideNavigationContorllerAnimator>
@property (nonatomic, assign) CGFloat slideMovement;
- (id)initWithSlideMovement:(CGFloat)slideMovement;
@end

View File

@ -0,0 +1,133 @@
//
// SlideNavigationContorllerAnimationSlide.m
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import "SlideNavigationContorllerAnimatorSlide.h"
@implementation SlideNavigationContorllerAnimatorSlide
#pragma mark - Initialization -
- (id)init
{
if (self = [self initWithSlideMovement:100])
{
}
return self;
}
- (id)initWithSlideMovement:(CGFloat)slideMovement
{
if (self = [super init])
{
self.slideMovement = slideMovement;
}
return self;
}
#pragma mark - SlideNavigationContorllerAnimation Methods -
- (void)prepareMenuForAnimation:(Menu)menu
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
UIInterfaceOrientation orientation= [SlideNavigationController sharedInstance].interfaceOrientation;
CGRect rect = menuViewController.view.frame;
if (UIInterfaceOrientationIsLandscape(orientation))
{
if (orientation == UIInterfaceOrientationLandscapeRight)
{
rect.origin.y = (menu == MenuLeft) ? self.slideMovement*-1 : self.slideMovement;
}
else
{
rect.origin.y = (menu == MenuRight) ? self.slideMovement*-1 : self.slideMovement;
}
}
else
{
if (orientation == UIInterfaceOrientationPortrait)
{
rect.origin.x = (menu == MenuLeft) ? self.slideMovement*-1 : self.slideMovement;
}
else
{
rect.origin.x = (menu == MenuRight) ? self.slideMovement*-1 : self.slideMovement;
}
}
menuViewController.view.frame = rect;
}
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
UIInterfaceOrientation orientation= [SlideNavigationController sharedInstance].interfaceOrientation;
NSInteger location = (menu == MenuLeft)
? (self.slideMovement * -1) + (self.slideMovement * progress)
: (self.slideMovement * (1-progress));
if (menu == MenuLeft)
location = (location > 0) ? 0 : location;
if (menu == MenuRight)
location = (location < 0) ? 0 : location;
CGRect rect = menuViewController.view.frame;
if (UIInterfaceOrientationIsLandscape(orientation))
{
rect.origin.y = (orientation == UIInterfaceOrientationLandscapeRight) ? location : location*-1;
}
else
{
rect.origin.x = (orientation == UIInterfaceOrientationPortrait) ? location : location*-1;
}
menuViewController.view.frame = rect;
}
- (void)clear
{
[self clearMenu:MenuLeft];
[self clearMenu:MenuRight];
}
#pragma mark - Private Method -
- (void)clearMenu:(Menu)menu
{
UIViewController *menuViewController = (menu == MenuLeft)
? [SlideNavigationController sharedInstance].leftMenu
: [SlideNavigationController sharedInstance].rightMenu;
UIInterfaceOrientation orientation= [SlideNavigationController sharedInstance].interfaceOrientation;
CGRect rect = menuViewController.view.frame;
if (UIInterfaceOrientationIsLandscape(orientation))
{
rect.origin.y = 0;
}
else
{
rect.origin.x = 0;
}
menuViewController.view.frame = rect;
}
@end

View File

@ -0,0 +1,16 @@
//
// SlideNavigationContorllerAnimationSlideAndFade.h
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationContorllerAnimatorSlideAndFade : NSObject <SlideNavigationContorllerAnimator>
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha fadeColor:(UIColor *)fadeColor andSlideMovement:(CGFloat)slideMovement;
@end

View File

@ -0,0 +1,62 @@
//
// SlideNavigationContorllerAnimationSlideAndFade.m
// SlideMenu
//
// Created by Aryan Gh on 1/26/14.
// Copyright (c) 2014 Aryan Ghassemi. All rights reserved.
//
#import "SlideNavigationContorllerAnimatorSlideAndFade.h"
#import "SlideNavigationContorllerAnimatorSlide.h"
#import "SlideNavigationContorllerAnimatorFade.h"
@interface SlideNavigationContorllerAnimatorSlideAndFade()
@property (nonatomic, strong) SlideNavigationContorllerAnimatorFade *fadeAnimation;
@property (nonatomic, strong) SlideNavigationContorllerAnimatorSlide *slideAnimation;
@end
@implementation SlideNavigationContorllerAnimatorSlideAndFade
#pragma mark - Initialization -
- (id)init
{
if (self = [self initWithMaximumFadeAlpha:.8 fadeColor:[UIColor blackColor] andSlideMovement:100])
{
}
return self;
}
- (id)initWithMaximumFadeAlpha:(CGFloat)maximumFadeAlpha fadeColor:(UIColor *)fadeColor andSlideMovement:(CGFloat)slideMovement
{
if (self = [super init])
{
self.fadeAnimation = [[SlideNavigationContorllerAnimatorFade alloc] initWithMaximumFadeAlpha:maximumFadeAlpha andFadeColor:fadeColor];
self.slideAnimation = [[SlideNavigationContorllerAnimatorSlide alloc] initWithSlideMovement:slideMovement];
}
return self;
}
#pragma mark - SlideNavigationContorllerAnimation Methods -
- (void)prepareMenuForAnimation:(Menu)menu
{
[self.fadeAnimation prepareMenuForAnimation:menu];
[self.slideAnimation prepareMenuForAnimation:menu];
}
- (void)animateMenu:(Menu)menu withProgress:(CGFloat)progress
{
[self.fadeAnimation animateMenu:menu withProgress:progress];
[self.slideAnimation animateMenu:menu withProgress:progress];
}
- (void)clear
{
[self.fadeAnimation clear];
[self.slideAnimation clear];
}
@end

View File

@ -39,27 +39,18 @@ typedef enum{
MenuRight,
}Menu;
typedef enum{
MenuRevealAnimationNone,
MenuRevealAnimationFade,
MenuRevealAnimationSlide,
MenuRevealAnimationSlideAndFade
}MenuRevealAnimation;
@protocol SlideNavigationContorllerAnimator;
@interface SlideNavigationController : UINavigationController <UINavigationControllerDelegate>
@property (nonatomic, assign) BOOL avoidSwitchingToSameClassViewController;
@property (nonatomic, assign) BOOL enableSwipeGesture;
@property (nonatomic, strong) UIViewController *rightMenu;
@property (nonatomic, strong) UIViewController *leftMenu;
@property (nonatomic, strong) UIBarButtonItem *leftbarButtonItem;
@property (nonatomic, strong) UIBarButtonItem *leftBarButtonItem;
@property (nonatomic, strong) UIBarButtonItem *rightBarButtonItem;
@property (nonatomic, assign) CGFloat portraitSlideOffset;
@property (nonatomic, assign) CGFloat landscapeSlideOffset;
@property (nonatomic, assign) MenuRevealAnimation menuRevealAnimation;
@property (nonatomic, assign) CGFloat menuRevealAnimationFadeMaximumAlpha;
@property (nonatomic, strong) UIColor *menuRevealAnimationFadeColor;
@property (nonatomic, assign) CGFloat menuRevealAnimationSlideMovement;
@property (nonatomic, strong) id <SlideNavigationContorllerAnimator> menuRevealAnimator;
+ (SlideNavigationController *)sharedInstance;
- (void)switchToViewController:(UIViewController *)viewController withCompletion:(void (^)())completion;

View File

@ -26,11 +26,11 @@
// THE SOFTWARE.
#import "SlideNavigationController.h"
#import "SlideNavigationContorllerAnimator.h"
@interface SlideNavigationController()
@property (nonatomic, strong) UITapGestureRecognizer *tapRecognizer;
@property (nonatomic, strong) UIPanGestureRecognizer *panRecognizer;
@property (nonatomic, strong) UIView *menuRevealFadeAnimationView;
@property (nonatomic, assign) CGPoint draggingPoint;
@end
@ -44,8 +44,6 @@
#define MENU_SHADOW_OPACITY 1
#define MENU_DEFAULT_SLIDE_OFFSET 60
#define MENU_FAST_VELOCITY_FOR_SWIPE_FOLLOW_DIRECTION 1200
#define MENU_REVEAL_ANIMATION_DEFAULT_SLIDE_MOVEMENT 100
#define MENU_REVEAL_ANIMATION_DEFAULT_FADE_MAXIMUM_ALPHA .8
#define STATUS_BAR_HEIGHT 20
static SlideNavigationController *singletonInstance;
@ -89,9 +87,6 @@ static SlideNavigationController *singletonInstance;
- (void)setup
{
self.menuRevealAnimationSlideMovement = MENU_REVEAL_ANIMATION_DEFAULT_SLIDE_MOVEMENT;
self.menuRevealAnimationFadeMaximumAlpha = MENU_REVEAL_ANIMATION_DEFAULT_FADE_MAXIMUM_ALPHA;
self.menuRevealAnimation = MenuRevealAnimationSlideAndFade;
self.landscapeSlideOffset = MENU_DEFAULT_SLIDE_OFFSET;
self.portraitSlideOffset = MENU_DEFAULT_SLIDE_OFFSET;
self.avoidSwitchingToSameClassViewController = YES;
@ -120,9 +115,6 @@ static SlideNavigationController *singletonInstance;
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Update rotation animation
[self updateMenuFrameAndTransformAccordingToOrientation];
// Avoid an ugnly shadow in background while rotating
self.view.layer.shadowOpacity = 0;
}
@ -131,6 +123,9 @@ static SlideNavigationController *singletonInstance;
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// Update rotation animation
[self updateMenuFrameAndTransformAccordingToOrientation];
self.view.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.view.bounds].CGPath;
// we set shadowOpacity to 0 in willRotateToInterfaceOrientation, after the rotation we want to add the shadow back
@ -139,17 +134,13 @@ static SlideNavigationController *singletonInstance;
- (void)updateMenuFrameAndTransformAccordingToOrientation
{
// Animate rotatation when menu is open and device rotates
CGAffineTransform transform = self.view.transform;
self.leftMenu.view.transform = transform;
self.rightMenu.view.transform = transform;
CGRect rect = self.view.frame;
self.leftMenu.view.frame = rect;
self.rightMenu.view.frame = rect;
// Move menus accordingly to avoid a weird animation during opening/closing menu after a rotation
[self updateMenuAnimation:MenuLeft];
[self updateMenuAnimation:MenuRight];
self.leftMenu.view.frame = [self initialRectForMenu];
self.rightMenu.view.frame = [self initialRectForMenu];
}
#pragma mark - Public Methods -
@ -278,7 +269,7 @@ static SlideNavigationController *singletonInstance;
- (UIBarButtonItem *)barButtonItemForMenu:(Menu)menu
{
SEL selector = (menu == MenuLeft) ? @selector(leftMenuSelected:) : @selector(righttMenuSelected:);
UIBarButtonItem *customButton = (menu == MenuLeft) ? self.leftbarButtonItem : self.rightBarButtonItem;
UIBarButtonItem *customButton = (menu == MenuLeft) ? self.leftBarButtonItem : self.rightBarButtonItem;
if (customButton)
{
@ -377,114 +368,54 @@ static SlideNavigationController *singletonInstance;
- (void)updateMenuAnimation:(Menu)menu
{
if (self.menuRevealAnimation == MenuRevealAnimationNone)
return;
UIViewController *menuViewController = (menu == MenuLeft) ? self.leftMenu : self.rightMenu;
CGFloat progress = (menu == MenuLeft)
? (self.horizontalLocation / self.maxXForDragging)
: (self.horizontalLocation / self.minXForDragging);
? (self.horizontalLocation / (self.horizontalSize - self.slideOffset))
: (self.horizontalLocation / ((self.horizontalSize - self.slideOffset) * -1));
[self.menuRevealAnimator animateMenu:menu withProgress:progress];
}
if (self.menuRevealAnimation == MenuRevealAnimationFade || self.menuRevealAnimation == MenuRevealAnimationSlideAndFade)
- (CGRect)initialRectForMenu
{
CGRect rect = self.view.frame;
rect.origin.x = 0;
rect.origin.y = 0;
BOOL isIos7 = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0");
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.menuRevealFadeAnimationView.frame = menuViewController.view.bounds;
[menuViewController.view addSubview:self.menuRevealFadeAnimationView];
self.menuRevealFadeAnimationView.alpha = self.menuRevealAnimationFadeMaximumAlpha - (self.menuRevealAnimationFadeMaximumAlpha *progress);
if (!isIos7)
{
// For some reasons in landscape belos the status bar is considered y=0, but in portrait it's considered y=20
rect.origin.x = (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) ? 0 : STATUS_BAR_HEIGHT;
rect.size.width = self.view.frame.size.width-STATUS_BAR_HEIGHT;
}
}
else
{
if (!isIos7)
{
// For some reasons in landscape belos the status bar is considered y=0, but in portrait it's considered y=20
rect.origin.y = (self.interfaceOrientation == UIInterfaceOrientationPortrait) ? STATUS_BAR_HEIGHT : 0;
rect.size.height = self.view.frame.size.height-STATUS_BAR_HEIGHT;
}
}
if (self.menuRevealAnimation == MenuRevealAnimationSlide || self.menuRevealAnimation == MenuRevealAnimationSlideAndFade)
{
NSInteger location = (menu == MenuLeft)
? (self.menuRevealAnimationSlideMovement * -1) + (self.menuRevealAnimationSlideMovement * progress)
: (self.menuRevealAnimationSlideMovement * (1-progress));
if (menu == MenuLeft)
location = (location > 0) ? 0 : location;
if (menu == MenuRight)
location = (location < 0) ? 0 : location;
CGRect rect = menuViewController.view.frame;
BOOL isIos7 = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0");
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
rect.origin.y = (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) ? location : location*-1;
if (!isIos7)
{
// For some reasons in landscape belos the status bar is considered y=0, but in portrait it's considered y=20
rect.origin.x = (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) ? 0 : STATUS_BAR_HEIGHT;
rect.size.width = self.view.frame.size.width-STATUS_BAR_HEIGHT;
}
}
else
{
rect.origin.x = (self.interfaceOrientation == UIInterfaceOrientationPortrait) ? location : location*-1;
if (!isIos7)
{
// For some reasons in landscape belos the status bar is considered y=0, but in portrait it's considered y=20
rect.origin.y = (self.interfaceOrientation == UIInterfaceOrientationPortrait) ? STATUS_BAR_HEIGHT : 0;
rect.size.height = self.view.frame.size.height-STATUS_BAR_HEIGHT;
}
}
menuViewController.view.frame = rect;
}
return rect;
}
- (void)prepareMenuForReveal:(Menu)menu forcePrepare:(BOOL)forcePrepare
{
// If menu is already open don't prepare, unless forcePrepare is set to true
if ([self isMenuOpen] && !forcePrepare)
return;
UIViewController *menuViewController = (menu == MenuLeft) ? self.leftMenu : self.rightMenu;
UIViewController *removingMenuViewController = (menu == MenuLeft) ? self.rightMenu : self.leftMenu;
[self updateMenuFrameAndTransformAccordingToOrientation];
// If menu is already open don't prepare, unless forcePrepare is set to true
// If already has been added to the view (has superview) it means it has been initialized so avoid reinitializing
if (menuViewController.view.superview)
if (([self isMenuOpen] && !forcePrepare) || menuViewController.view.superview)
return;
if (self.menuRevealAnimation == MenuRevealAnimationFade || self.menuRevealAnimation == MenuRevealAnimationSlideAndFade)
{
self.menuRevealFadeAnimationView.alpha = self.menuRevealAnimationFadeMaximumAlpha;
self.menuRevealFadeAnimationView.frame = menuViewController.view.bounds;
}
if (self.menuRevealAnimation == MenuRevealAnimationSlide || self.menuRevealAnimation == MenuRevealAnimationSlideAndFade)
{
CGRect rect = menuViewController.view.frame;
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
rect.origin.y = (menu == MenuLeft) ? self.menuRevealAnimationSlideMovement*-1 : self.menuRevealAnimationSlideMovement;
}
else
{
rect.origin.y = (menu == MenuRight) ? self.menuRevealAnimationSlideMovement*-1 : self.menuRevealAnimationSlideMovement;
}
}
else
{
if (self.interfaceOrientation == UIInterfaceOrientationPortrait)
{
rect.origin.x = (menu == MenuLeft) ? self.menuRevealAnimationSlideMovement*-1 : self.menuRevealAnimationSlideMovement;
}
else
{
rect.origin.x = (menu == MenuRight) ? self.menuRevealAnimationSlideMovement*-1 : self.menuRevealAnimationSlideMovement;
}
}
menuViewController.view.frame = rect;
}
[self.menuRevealAnimator prepareMenuForAnimation:menu];
[removingMenuViewController.view removeFromSuperview];
[self.view.window insertSubview:menuViewController.view atIndex:0];
@ -581,7 +512,9 @@ static SlideNavigationController *singletonInstance;
if (aPanRecognizer.state == UIGestureRecognizerStateBegan)
{
[self prepareMenuForReveal:menu forcePrepare:YES];
if (![self isMenuOpen])
[self prepareMenuForReveal:menu forcePrepare:YES];
self.draggingPoint = translation;
lastMenu = menu;
}
@ -710,22 +643,11 @@ static SlideNavigationController *singletonInstance;
}
}
- (UIView *)menuRevealFadeAnimationView
- (void)setMenuRevealAnimator:(id<SlideNavigationContorllerAnimator>)menuRevealAnimator
{
if (!_menuRevealFadeAnimationView)
{
_menuRevealFadeAnimationView = [[UIView alloc] init];
_menuRevealFadeAnimationView.backgroundColor = [UIColor blackColor];
_menuRevealFadeAnimationView.frame = self.view.bounds;
}
[self.menuRevealAnimator clear];
return _menuRevealFadeAnimationView;
}
- (void)setMenuRevealAnimationFadeColor:(UIColor *)menuRevealAnimationFadeColor
{
_menuRevealAnimationFadeColor = menuRevealAnimationFadeColor;
self.menuRevealFadeAnimationView.backgroundColor = menuRevealAnimationFadeColor;
_menuRevealAnimator = menuRevealAnimator;
}
@end

View File

@ -15,8 +15,9 @@
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="T7T-Ke-Ksy">
<rect key="frame" x="0.0" y="20" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="0.0"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="rightMenuCell" textLabel="69X-Zn-twq" style="IBUITableViewCellStyleDefault" id="Pb7-aS-2IS">
<rect key="frame" x="0.0" y="22" width="320" height="44"/>