Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanoa committed Feb 19, 2013
1 parent 4bdae8a commit 67f9377
Show file tree
Hide file tree
Showing 19 changed files with 504 additions and 237 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# CHANGELOG

Version 1.2.0
* Fixed issues #41,#40,#38,#33
* Changes to SASlideMenuDataSource
* SASlideMenuStatic example now cache the content view controllers
* Added CHANGELOG.md
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ The repository is an Xcode 4 project that contains two example of the usage of t
# Usage
You can use SASlide menu with both static cells and dynamic cell prototypes. In the project yuo will find two different target that use both type of cells to create a slide menu.
To use it in your project follow these steps:
* Add the SASlideMenu subdir and it's contents to your project
* Add a new class that inherits from **SASlideMenuViewController** and include/implement **SASlideMenuDataSource** and **SASlideMenuDelegate**.
* **SASlideMenuDataSource** is where you will code your customization while **SASlideMenuDelegate** is where you will add your code to implement the behavior of your app related to the **SASlideMenu** events.

* Add the SASlideMenu subdir and his content to your project
* Add a new class that inherit from **SASlideMenuViewController** and implement **SASlideMenuDatSource** and **SASlideMenuDelegate**. **SASlideMenuDataSource** is where you will code your customization while **SASlideMenuDelegate** is where you will add your code to implement the behavior of your app related to the SASlideMenu events. There are a minimum **SASlideMenuDataSource** methods that are required while the **SASlideMenuDelegate** is entirely optional.
* Add a new **SASlideMenuRootViewController** in your storyboard
* Add a **UITableViewController** and make it of the **SASlideMenuViewController** subclass you already implemented and customize it in accordance with your needs.
* Connect the **SASlideMenuRootViewController** with your subclass with a custom segue of type **SASlideMenuLeftMenuSegue**, set the segue identifier to **leftMenu**.
* To add Content ViewController you have to to do the following:
* Create your content view controller and embed it in a **UINavigationController**
* Connet it to the SASlideMenuViewController via a SASlideMenuContentSegue. If you are using static cells simply connect from the corresponding cell. If you are using dynamic cell prototype connect it from the VieController and assign an identifier that will be returned in the **sugueIdForIndexPath:** method linked to the desired indexPath.
* Connet it to the **SASlideMenuViewController** via a SASlideMenuContentSegue. If you are using static cells and you simply connect from the corresponding cell it is not possible to cache the content view controller and the **segueIdForIndexPath** must not be implemented. If you are using dynamic cell prototype or you are using static cells and you want to cache the content view controller, assign an identifier that will be returned in the **sugueIdForIndexPath:** method linked to the desired indexPath.
* To add a right menu, connect a new **UINavigationController** containing a **UITableViewController** to the menu view controller using a **SASlideMenuRightMenuSegue** and set the segue identifier to **rightMenu**. The new view controller will contain the right menu and will allow navigation.

Test it and you are done!
Expand Down Expand Up @@ -55,4 +56,4 @@ It needs iOS 5.1
*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.*
*THE SOFTWARE.*
22 changes: 19 additions & 3 deletions SASlideMenu.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
7B27435A16D2820600F89C69 /* LightViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B27435916D2820600F89C69 /* LightViewController.m */; };
7B27435C16D3638300F89C69 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 7B27435B16D3638300F89C69 /* CHANGELOG.md */; };
7BC688BF16A6FD08004ED00D /* SASlideMenuRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC688BE16A6FD08004ED00D /* SASlideMenuRootViewController.m */; };
7BC688FC16A99DB2004ED00D /* SASlideMenuContentSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC688F416A99DA3004ED00D /* SASlideMenuContentSegue.m */; };
7BC688FD16A99DB2004ED00D /* SASlideMenuLeftMenuSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC688F616A99DA3004ED00D /* SASlideMenuLeftMenuSegue.m */; };
Expand Down Expand Up @@ -121,6 +123,9 @@
7B1141A4161B621000549B42 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
7B1141A7161B658D00549B42 /* Screenshot-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Screenshot-Landscape.png"; sourceTree = "<group>"; };
7B1141A8161B658D00549B42 /* Screenshot-Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Screenshot-Portrait.png"; sourceTree = "<group>"; };
7B27435816D2820600F89C69 /* LightViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LightViewController.h; sourceTree = "<group>"; };
7B27435916D2820600F89C69 /* LightViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LightViewController.m; sourceTree = "<group>"; };
7B27435B16D3638300F89C69 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG.md; sourceTree = "<group>"; };
7B28D2A2165BF464000EE929 /* ExampleDynamicMenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExampleDynamicMenuViewController.h; path = ../SASlideMenu/ExampleDynamicMenuViewController.h; sourceTree = "<group>"; };
7B28D2A3165BF464000EE929 /* ExampleDynamicMenuViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ExampleDynamicMenuViewController.m; path = ../SASlideMenu/ExampleDynamicMenuViewController.m; sourceTree = "<group>"; };
7B28D2A5165CCB10000EE929 /* ColoredViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColoredViewController.h; path = ../SASlideMenu/ColoredViewController.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -277,6 +282,7 @@
7B56BF48163C2ECF00D9C143 /* Icon.png */,
7B1141A4161B621000549B42 /* Default-568h@2x.png */,
7BF0A6B915DE682A00B3B57F /* README.md */,
7B27435B16D3638300F89C69 /* CHANGELOG.md */,
7B8C3FE415D8D55800E42A41 /* SASlideMenu */,
7BDBF427166CC79300FDA327 /* SASlideMenuDynamic */,
7BDBF46F166CDEB100FDA327 /* SASlideMenuStatic */,
Expand Down Expand Up @@ -367,6 +373,8 @@
7BF0A6B115DE499F00B3B57F /* MenuCell.m */,
7B3B2D5215DCE0E1009F4AB8 /* DarkViewController.h */,
7B3B2D5315DCE0E1009F4AB8 /* DarkViewController.m */,
7B27435816D2820600F89C69 /* LightViewController.h */,
7B27435916D2820600F89C69 /* LightViewController.m */,
7B5B88E1163B23B300D02C1F /* ShadesViewController.h */,
7B5B88E2163B23B300D02C1F /* ShadesViewController.m */,
7B8C3FF315D8D55800E42A41 /* ExampleStaticMenuViewController.h */,
Expand Down Expand Up @@ -396,6 +404,8 @@
7BF0A68615DE492E00B3B57F /* SASlideMenu */ = {
isa = PBXGroup;
children = (
7BF0A68915DE495500B3B57F /* SASlideMenuDataSource.h */,
7B5CA6EE1682121B006E6993 /* SASlideMenuDelegate.h */,
7BC688F316A99DA3004ED00D /* SASlideMenuContentSegue.h */,
7BC688F416A99DA3004ED00D /* SASlideMenuContentSegue.m */,
7BC688F516A99DA3004ED00D /* SASlideMenuLeftMenuSegue.h */,
Expand All @@ -406,8 +416,6 @@
7BFEA28616C0FACF00455A22 /* SASlideMenuPushSegue.m */,
7BC688F716A99DA4004ED00D /* SASlideMenuViewController.h */,
7BC688F816A99DA4004ED00D /* SASlideMenuViewController.m */,
7BF0A68915DE495500B3B57F /* SASlideMenuDataSource.h */,
7B5CA6EE1682121B006E6993 /* SASlideMenuDelegate.h */,
7BC688BD16A6FD08004ED00D /* SASlideMenuRootViewController.h */,
7BC688BE16A6FD08004ED00D /* SASlideMenuRootViewController.m */,
7BFEA28816C1545000455A22 /* SASlideMenuRightMenuViewController.h */,
Expand Down Expand Up @@ -462,7 +470,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = SASlideMenu;
LastUpgradeCheck = 0440;
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Stefano Antonelli";
};
buildConfigurationList = 7B8C3FD415D8D55800E42A41 /* Build configuration list for PBXProject "SASlideMenu" */;
Expand Down Expand Up @@ -565,6 +573,7 @@
7BDBF4AA166CDF8200FDA327 /* rowselected@2x.png in Resources */,
7BDBF4B1166CE51200FDA327 /* Icon.png in Resources */,
7BDBF4B2166CE51900FDA327 /* Icon@2x.png in Resources */,
7B27435C16D3638300F89C69 /* CHANGELOG.md in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -608,6 +617,7 @@
7BC688FE16A99DB2004ED00D /* SASlideMenuViewController.m in Sources */,
7BC6890216A9F51C004ED00D /* SASlideMenuRootViewController.m in Sources */,
7BFEA28E16C2573F00455A22 /* SASlideMenuNavigationController.m in Sources */,
7B27435A16D2820600F89C69 /* LightViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -664,6 +674,9 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
Expand Down Expand Up @@ -691,6 +704,9 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
Expand Down
2 changes: 1 addition & 1 deletion SASlideMenu/ColoredDetailViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#import <UIKit/UIKit.h>

@interface ColoredDetailViewController : UIViewController
@interface ColoredDetailViewController : UITableViewController
@property(nonatomic,strong) IBOutlet UIView* colorBox;
@property(nonatomic,strong) IBOutlet UILabel* hue;
@property(nonatomic,strong) IBOutlet UILabel* brightness;
Expand Down
38 changes: 20 additions & 18 deletions SASlideMenu/ExampleDynamicMenuViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ -(id) initWithCoder:(NSCoder *)aDecoder{
self.slideMenuDataSource = self;
self.slideMenuDelegate = self;
self.selectedBrightness = 0.3;
self.selectedHue = 0.0;

self.selectedHue = 0.0;
}
return self;
}
Expand All @@ -50,19 +49,16 @@ -(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
return YES;
}

-(void) prepareForSwitchToContentViewController:(UIViewController *)content{
UINavigationController* navigationController = (UINavigationController*)content;
ColoredViewController* coloredViewController = (ColoredViewController*) navigationController.topViewController;

[coloredViewController setBackgroundHue:selectedHue brightness:selectedBrightness];
}
#pragma mark -
#pragma mark SASlideMenuDataSource

// The SASlideMenuDataSource provides the initial segueid that represents the initial visibile view controller, the eventual additional configuration to the menu button and the mapping for each indexPath to the segues for the content controllers



-(void) prepareForSwitchToContentViewController:(UINavigationController *)content{
UIViewController* controller = [content.viewControllers objectAtIndex:0];
if ([controller isKindOfClass:[ColoredViewController class]]) {
ColoredViewController* coloredViewController = (ColoredViewController*) controller;
[coloredViewController setBackgroundHue:selectedHue brightness:selectedBrightness];
}
}

// It configure the menu button. The beahviour of the button should not be modified
-(void) configureMenuButton:(UIButton *)menuButton{
Expand All @@ -74,6 +70,7 @@ -(void) configureMenuButton:(UIButton *)menuButton{
[menuButton setAdjustsImageWhenDisabled:NO];
}

// It configure the right menu button. The beahviour of the button should not be modified
-(void) configureRightMenuButton:(UIButton *)menuButton{
menuButton.frame = CGRectMake(0, 0, 40, 29);
[menuButton setImage:[UIImage imageNamed:@"menuright.png"] forState:UIControlStateNormal];
Expand All @@ -82,9 +79,10 @@ -(void) configureRightMenuButton:(UIButton *)menuButton{
[menuButton setAdjustsImageWhenHighlighted:NO];
[menuButton setAdjustsImageWhenDisabled:NO];
}

// This is the segue you want visibile when the controller is loaded the first time
-(NSString*) initialSegueId{
return @"colored";
-(NSIndexPath*) selectedIndexPath{
return [NSIndexPath indexPathForRow:0 inSection:0];
}

// It maps each indexPath to the segueId to be used. The segue is performed only the first time the controller needs to loaded, subsequent switch to the content controller will use the already loaded controller
Expand All @@ -95,21 +93,25 @@ -(NSString*) segueIdForIndexPath:(NSIndexPath *)indexPath{
}
return @"colored";
}

-(Boolean) slideOutThenIn{
return NO;
}
//Enable caching for the Controller at the provided indexPath
-(Boolean) allowContentViewControllerCachingForIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row ==0) {
return NO;
}
return YES;
}

-(Boolean) hasRightMenuForSegueId:(NSString *)segueId{
if ([segueId isEqualToString:@"coloredNoRightMenu"]) {
return NO;
//Enable the right menu for the controller linked to the Segue indentified by the provided segueId
-(Boolean) hasRightMenuForIndexPath:(NSIndexPath *)indexPath{

if (indexPath.section == 0) {
return YES;
}
return YES;
return NO;
}

#pragma mark -
Expand Down
30 changes: 25 additions & 5 deletions SASlideMenu/ExampleStaticMenuViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import "ExampleStaticMenuViewController.h"
#import "MenuCell.h"
#import "DarkViewController.h"

#import "LightViewController.h"
@interface ExampleStaticMenuViewController ()

@end
Expand Down Expand Up @@ -44,9 +44,23 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
#pragma mark SASlideMenuDataSource
// The SASlideMenuDataSource is used to provide the initial segueid that represents the initial visibile view controller and to provide eventual additional configuration to the menu button

// This is the segue you want visibile when the controller is loaded the first time
-(NSString*) initialSegueId{
return @"dark";
// This is the indexPath selected at start-up
-(NSIndexPath*) selectedIndexPath{
return [NSIndexPath indexPathForRow:0 inSection:0];
}

-(NSString*) segueIdForIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) {
return @"dark";
}else if (indexPath.row == 1){
return @"light";
}else{
return @"shades";
}
}

-(Boolean) allowContentViewControllerCachingForIndexPath:(NSIndexPath *)indexPath{
return YES;
}

// This is used to configure the menu button. The beahviour of the button should not be modified
Expand All @@ -71,7 +85,13 @@ -(void) configureSlideLayer:(CALayer *)layer{
-(CGFloat) leftMenuVisibleWidth{
return 280;
}

-(void) prepareForSwitchToContentViewController:(UINavigationController *)content{
UIViewController* controller = [content.viewControllers objectAtIndex:0];
if ([controller isKindOfClass:[LightViewController class]]) {
LightViewController* lightViewController = (LightViewController*)controller;
lightViewController.menuViewController = self;
}
}
#pragma mark -
#pragma mark SASlideMenuDelegate

Expand Down
25 changes: 12 additions & 13 deletions SASlideMenu/SASlideMenu/SASlideMenuContentSegue.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ -(void) perform{
navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:menuButton];

Boolean hasRightMenu = NO;
rootController.isRightMenuEnabled = NO;
NSIndexPath* selectedIndexPath = [rootController.leftMenu.tableView indexPathForSelectedRow];

if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(hasRightMenuForSegueId:)]) {
hasRightMenu = [rootController.leftMenu.slideMenuDataSource hasRightMenuForSegueId:self.identifier];
if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(hasRightMenuForIndexPath:)]) {
hasRightMenu = [rootController.leftMenu.slideMenuDataSource hasRightMenuForIndexPath:selectedIndexPath];
}
if (hasRightMenu) {
rootController.isRightMenuEnabled = YES;
if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(configureRightMenuButton:)]) {
UIButton* rightMenuButton = [[UIButton alloc] init];
[rootController.leftMenu.slideMenuDataSource configureRightMenuButton:rightMenuButton];
Expand All @@ -56,19 +58,16 @@ -(void) perform{

[rootController switchToContentViewController:destination];

if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(sugueIdForIndexPath:)]) {
if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(segueIdForIndexPath:)]) {
[rootController addContentViewController:destination withIndexPath:selectedIndexPath];
}
if ([rootController.leftMenu.slideMenuDataSource respondsToSelector:@selector(hasRightMenuForSegueId:)]) {
Boolean hasRightMenu = [rootController.leftMenu.slideMenuDataSource hasRightMenuForSegueId:self.identifier];
if (hasRightMenu) {
rootController.isRightMenuEnabled = YES;
}else{
rootController.isRightMenuEnabled = NO;
}
}else{
rootController.isRightMenuEnabled = NO;
}

UIPanGestureRecognizer* panGesture= [[UIPanGestureRecognizer alloc] initWithTarget:rootController action:@selector(panItem:)];
[panGesture setMaximumNumberOfTouches:2];
[panGesture setDelegate:source];
[panGesture setCancelsTouchesInView:NO];

[destination.view addGestureRecognizer:panGesture];
}

@end
30 changes: 23 additions & 7 deletions SASlideMenu/SASlideMenu/SASlideMenuDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,43 @@
// Copyright (c) 2012 Stefano Antonelli. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol SASlideMenuDataSource <NSObject>

@required
-(NSString*) initialSegueId;
-(void) configureMenuButton:(UIButton*) menuButton;

@optional
-(void) prepareForSwitchToContentViewController:(UIViewController *)content;

//It is used to prepare the Content View Controller before it will be displayed.
//It is called for each selection of the menu.
-(void) prepareForSwitchToContentViewController:(UINavigationController *)content;

//Maps menu rows to segueId. It is a required method for table with dynamic cell prototype.
//It is also required if you want to use static table but you need to cache content view controllers.
-(NSString*) segueIdForIndexPath:(NSIndexPath*) indexPath;
-(Boolean) hasRightMenuForSegueId:(NSString*) segueId;

//It returns the initially selected menu row. If not implemented the menu is initially displayed without selection.
-(NSIndexPath*) selectedIndexPath;

// It is used to provide a custom configuration for the menu button.
-(void) configureMenuButton:(UIButton*) menuButton;

// It is used to selectively activate the right menu button. It is a mandatory method if you need a right button.
-(Boolean) hasRightMenuForIndexPath:(NSIndexPath*) indexPath;
// It is used to provide a custom configuration for the right menu button. It is a mandatory method if you need a right button.
-(void) configureRightMenuButton:(UIButton*) menuButton;

// It is used to provide a custom configuration for the content CALayer, useful to change shadow style.
-(void) configureSlideLayer:(CALayer*) layer;

// The visibile widht of the left menu
-(CGFloat) leftMenuVisibleWidth;

// The visibile widht of the right menu
-(CGFloat) rightMenuVisibleWidth;

// If it returns true when switching between content view controller the deselected one will slide out before the selected one will slide in.
-(Boolean) slideOutThenIn;

// It is used to selectively allow content view controller caching.
-(Boolean) allowContentViewControllerCachingForIndexPath:(NSIndexPath*) indexPath;

@end
Loading

0 comments on commit 67f9377

Please sign in to comment.