diff --git a/README.md b/README.md index 2dc25f7..b81e2dd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ A UIViewController subclass for revealing a rear (left and/or right) view controller behind a front controller, inspired by the Facebook app, done right! + +## NOTE ( Upgrading to Version 2.1) + +This version incorporates a new approach to Story Boards support. + +* There are now two different segue classes, SWRevealViewControllerSegueSetController and SWRevealViewControllerSeguePushController. The first one is meant to set the revealViewController with the initial controllers from the story board. The second one is used to push controllers to the front with animation. The former SWRevealViewControllerSegue still works but it has been deprecated. +* A new StoryBoard example, RevealControllerStoryBoardExample2, has been added to demonstrate the use of the new segue classes. More responsability has been moved to the Story Board design while simplifying the SWRevealViewController implementation. + ## IMPORTANT NOTE: (Upgrading to Version 2.0) A number of changes have been made on version 2.0 that may break your existing project. In case you are not ready to upgrade you can continue using previous versions. The last commit before 2.0.0 was tagged v1.1.3. The important changes that affect 2.0.0 are described next. diff --git a/RevealControllerStoryboardExample/.DS_Store b/RevealControllerStoryboardExample/.DS_Store index 2f34dff..8c13292 100644 Binary files a/RevealControllerStoryboardExample/.DS_Store and b/RevealControllerStoryboardExample/.DS_Store differ diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.h b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.h new file mode 100755 index 0000000..5085a5b --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.m b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.m new file mode 100755 index 0000000..849fb72 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/AppDelegate.m @@ -0,0 +1,46 @@ +// +// AppDelegate.m +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.h b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.h new file mode 100755 index 0000000..e70bf3f --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.h @@ -0,0 +1,15 @@ +// +// ColorViewController.h +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import + +@interface ColorViewController : UIViewController +@property (nonatomic, strong) IBOutlet UILabel* label; +@property (nonatomic, strong) UIColor* color; +@property (nonatomic, strong) NSString* text; +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.m b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.m new file mode 100755 index 0000000..99ba03a --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/ColorViewController.m @@ -0,0 +1,29 @@ +// +// ColorViewController.m +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import "ColorViewController.h" + +@interface ColorViewController () +@property (nonatomic) IBOutlet UIBarButtonItem* revealButtonItem; +@end + +@implementation ColorViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.revealButtonItem setTarget: self.revealViewController]; + [self.revealButtonItem setAction: @selector( revealToggle: )]; + [self.navigationController.navigationBar addGestureRecognizer: self.revealViewController.panGestureRecognizer]; + + _label.text = _text; + _label.textColor = _color; +} + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default-568h@2x.png b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default-568h@2x.png new file mode 100755 index 0000000..0891b7a Binary files /dev/null and b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default-568h@2x.png differ diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default.png b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default.png new file mode 100755 index 0000000..4c8ca6f Binary files /dev/null and b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default.png differ diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default@2x.png b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default@2x.png new file mode 100755 index 0000000..35b84cf Binary files /dev/null and b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/Default@2x.png differ diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.h b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.h new file mode 100755 index 0000000..839b2c9 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.h @@ -0,0 +1,13 @@ +// +// MapViewController.h +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import + +@interface MapViewController : UIViewController + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.m b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.m new file mode 100755 index 0000000..482f026 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MapViewController.m @@ -0,0 +1,26 @@ +// +// MapViewController.m +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import "MapViewController.h" + +@interface MapViewController () +@property (nonatomic) IBOutlet UIBarButtonItem* revealButtonItem; +@end + +@implementation MapViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.revealButtonItem setTarget: self.revealViewController]; + [self.revealButtonItem setAction: @selector( revealToggle: )]; + [self.navigationController.navigationBar addGestureRecognizer: self.revealViewController.panGestureRecognizer]; +} + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.h b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.h new file mode 100755 index 0000000..e271420 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.h @@ -0,0 +1,17 @@ +// +// MenuViewController.h +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import + +@interface SWUITableViewCell : UITableViewCell +@property (nonatomic) IBOutlet UILabel *label; +@end + +@interface MenuViewController : UITableViewController + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.m b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.m new file mode 100755 index 0000000..c3e0512 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/MenuViewController.m @@ -0,0 +1,102 @@ +// +// MenuViewController.m +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import "MenuViewController.h" +#import "ColorViewController.h" + +@implementation SWUITableViewCell +@end + +@implementation MenuViewController + +- (void) prepareForSegueB: (UIStoryboardSegue *) segue sender: (id) sender +{ + // configure the destination view controller: + if ( [segue.destinationViewController isKindOfClass: [ColorViewController class]] && + [sender isKindOfClass:[UITableViewCell class]] ) + { + UILabel* c = [(SWUITableViewCell *)sender label]; + ColorViewController* cvc = segue.destinationViewController; + + cvc.color = c.textColor; + cvc.text = c.text; + } + + // configure the segue. + if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) + { + SWRevealViewControllerSegue* rvcs = (SWRevealViewControllerSegue*) segue; + + SWRevealViewController* rvc = self.revealViewController; + NSAssert( rvc != nil, @"oops! must have a revealViewController" ); + + NSAssert( [rvc.frontViewController isKindOfClass: [UINavigationController class]], @"oops! for this segue we want a permanent navigation controller in the front!" ); + + rvcs.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) + { + UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:dvc]; + [rvc pushFrontViewController:nc animated:YES]; + }; + } +} + + +- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender +{ + // configure the destination view controller: + if ( [sender isKindOfClass:[UITableViewCell class]] ) + { + UILabel* c = [(SWUITableViewCell *)sender label]; + UINavigationController *navController = segue.destinationViewController; + ColorViewController* cvc = [navController childViewControllers].firstObject; + if ( [cvc isKindOfClass:[ColorViewController class]] ) + { + cvc.color = c.textColor; + cvc.text = c.text; + } + } +} + + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return 3; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + + switch ( indexPath.row ) + { + case 0: + CellIdentifier = @"map"; + break; + + case 1: + CellIdentifier = @"blue"; + break; + + case 2: + CellIdentifier = @"red"; + break; + } + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; + + return cell; +} + +@end diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/InfoPlist.strings b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/InfoPlist.strings new file mode 100755 index 0000000..477b28f --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard-iPad.storyboard b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard-iPad.storyboard new file mode 100755 index 0000000..5e5cfe2 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard-iPad.storyboard @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard.storyboard b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard.storyboard new file mode 100755 index 0000000..aa83630 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/en.lproj/MainStoryboard.storyboard @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/main.m b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/main.m new file mode 100755 index 0000000..bb7b798 --- /dev/null +++ b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/main.m @@ -0,0 +1,18 @@ +// +// main.m +// RevealControllerStoryboardExample +// +// Created by Nick Hodapp on 1/9/13. +// Copyright (c) 2013 CoDeveloper. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon.png b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon.png new file mode 100755 index 0000000..4a4d467 Binary files /dev/null and b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon.png differ diff --git a/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon@2x.png b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon@2x.png new file mode 100755 index 0000000..08dc402 Binary files /dev/null and b/RevealControllerStoryboardExample2/RevealControllerStoryboardExample2/reveal-icon@2x.png differ diff --git a/SWRevealViewController.podspec b/SWRevealViewController.podspec index c425b9d..9258e43 100644 --- a/SWRevealViewController.podspec +++ b/SWRevealViewController.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SWRevealViewController" - s.version = "2.0.2" + s.version = "2.1.0" s.summary = "A UIViewController subclass for presenting two view controllers inspired in the Facebook app, done right." s.homepage = "https://github.com/John-Lluch/SWRevealViewController" s.license = "MIT" diff --git a/SWRevealViewController/SWRevealViewController.h b/SWRevealViewController/SWRevealViewController.h index 8103d94..4cb9972 100755 --- a/SWRevealViewController/SWRevealViewController.h +++ b/SWRevealViewController/SWRevealViewController.h @@ -28,6 +28,12 @@ RELEASE NOTES + Version 2.1.0 + + - Removed SWDirectionPanGestureRecognizer. Horizontal panning is filtered on the shouldBegin delegate. This is cleaner, I hope it does not break previous funcionality + - Took a cleaner approach to storyboard support. SWRevealViewControllerSegue is now deprecated and you should use SWRevealViewControllerSegueSetController and SWRevealViewControllerSeguePushController instead. + - A minor change on the autoresizingMask of the internal views to fix a glitch on iOS8. This should not affect iOS7 + Version 2.0.2 (Current Version) - Added new delegates for better control of gesture recognizers @@ -155,15 +161,15 @@ typedef enum - (id)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController; // Rear view controller, can be nil if not used -@property (strong, nonatomic) UIViewController *rearViewController; +@property (nonatomic) UIViewController *rearViewController; - (void)setRearViewController:(UIViewController *)rearViewController animated:(BOOL)animated; // Optional right view controller, can be nil if not used -@property (strong, nonatomic) UIViewController *rightViewController; +@property (nonatomic) UIViewController *rightViewController; - (void)setRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated; // Front view controller, can be nil on initialization but must be supplied by the time the view is loaded -@property (strong, nonatomic) UIViewController *frontViewController; +@property (nonatomic) UIViewController *frontViewController; - (void)setFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated; // Sets the frontViewController using a default set of chained animations consisting on moving the @@ -172,7 +178,7 @@ typedef enum // Front view position, use this to set a particular position state on the controller // On initialization it is set to FrontViewPositionLeft -@property (assign, nonatomic) FrontViewPosition frontViewPosition; +@property (nonatomic) FrontViewPosition frontViewPosition; // Chained animation of the frontViewController position. You can call it several times in a row to achieve // any set of animations you wish. Animations will be chained and performed one after the other. @@ -186,8 +192,8 @@ typedef enum // The following methods are meant to be directly connected to the action method of a button // to perform user triggered postion change of the controller views. This is ussually added to a // button on top left or right of the frontViewController -- (void)revealToggle:(id)sender; -- (void)rightRevealToggle:(id)sender; // <-- simetric implementation of the above for the rightViewController +- (IBAction)revealToggle:(id)sender; +- (IBAction)rightRevealToggle:(id)sender; // <-- simetric implementation of the above for the rightViewController // The following method will provide a panGestureRecognizer suitable to be added to any view // in order to perform usual drag and swipe gestures to reveal the rear views. This is usually added to the top bar @@ -208,58 +214,58 @@ typedef enum // Defines how much of the rear or right view is shown, default is 260. A negative value indicates that the reveal width should be // computed by substracting the full front view width, so the revealed frontView width is constant. -@property (assign, nonatomic) CGFloat rearViewRevealWidth; -@property (assign, nonatomic) CGFloat rightViewRevealWidth; // <-- simetric implementation of the above for the rightViewController +@property (nonatomic) CGFloat rearViewRevealWidth; +@property (nonatomic) CGFloat rightViewRevealWidth; // <-- simetric implementation of the above for the rightViewController // Defines how much of an overdraw can occur when dragging further than 'rearViewRevealWidth', default is 60. -@property (assign, nonatomic) CGFloat rearViewRevealOverdraw; -@property (assign, nonatomic) CGFloat rightViewRevealOverdraw; // <-- simetric implementation of the above for the rightViewController +@property (nonatomic) CGFloat rearViewRevealOverdraw; +@property (nonatomic) CGFloat rightViewRevealOverdraw; // <-- simetric implementation of the above for the rightViewController // Defines how much displacement is applied to the rear view when animating or dragging the front view, default is 40. -@property (assign, nonatomic) CGFloat rearViewRevealDisplacement; -@property (assign, nonatomic) CGFloat rightViewRevealDisplacement; +@property (nonatomic) CGFloat rearViewRevealDisplacement; +@property (nonatomic) CGFloat rightViewRevealDisplacement; // Defines a width on the border of the view attached to the panGesturRecognizer where the gesture is allowed, // default is 0 which means no restriction. -@property (assign, nonatomic) CGFloat draggableBorderWidth; +@property (nonatomic) CGFloat draggableBorderWidth; // If YES (the default) the controller will bounce to the Left position when dragging further than 'rearViewRevealWidth' -@property (assign, nonatomic) BOOL bounceBackOnOverdraw; -@property (assign, nonatomic) BOOL bounceBackOnLeftOverdraw; +@property (nonatomic) BOOL bounceBackOnOverdraw; +@property (nonatomic) BOOL bounceBackOnLeftOverdraw; // If YES (default is NO) the controller will allow permanent dragging up to the rightMostPosition -@property (assign, nonatomic) BOOL stableDragOnOverdraw; -@property (assign, nonatomic) BOOL stableDragOnLeftOverdraw; // <-- simetric implementation of the above for the rightViewController +@property (nonatomic) BOOL stableDragOnOverdraw; +@property (nonatomic) BOOL stableDragOnLeftOverdraw; // <-- simetric implementation of the above for the rightViewController // If YES (default is NO) the front view controller will be ofsseted vertically by the height of a navigation bar. // Use this on iOS7 when you add an instance of RevealViewController as a child of a UINavigationController (or another SWRevealViewController) // and you want the front view controller to be presented below the navigation bar of its UINavigationController grand parent . // The rearViewController will still appear full size and blurred behind the navigation bar of its UINavigationController grand parent -@property (assign, nonatomic) BOOL presentFrontViewHierarchically; +@property (nonatomic) BOOL presentFrontViewHierarchically; // Velocity required for the controller to toggle its state based on a swipe movement, default is 300 -@property (assign, nonatomic) CGFloat quickFlickVelocity; +@property (nonatomic) CGFloat quickFlickVelocity; // Duration for the revealToggle animation, default is 0.25 -@property (assign, nonatomic) NSTimeInterval toggleAnimationDuration; +@property (nonatomic) NSTimeInterval toggleAnimationDuration; // Duration for animated replacement of view controllers -@property (assign, nonatomic) NSTimeInterval replaceViewAnimationDuration; +@property (nonatomic) NSTimeInterval replaceViewAnimationDuration; // Defines the radius of the front view's shadow, default is 2.5f -@property (assign, nonatomic) CGFloat frontViewShadowRadius; +@property (nonatomic) CGFloat frontViewShadowRadius; // Defines the radius of the front view's shadow offset default is {0.0f,2.5f} -@property (assign, nonatomic) CGSize frontViewShadowOffset; +@property (nonatomic) CGSize frontViewShadowOffset; //Defines the front view's shadow opacity, default is 1.0f -@property (assign, nonatomic) CGFloat frontViewShadowOpacity; +@property (nonatomic) CGFloat frontViewShadowOpacity; // The class properly handles all the relevant calls to appearance methods on the contained controllers. // Moreover you can assign a delegate to let the class inform you on positions and animation activity. // Delegate -@property (weak, nonatomic) id delegate; +@property (nonatomic,weak) id delegate; @end @@ -334,13 +340,29 @@ typedef enum @end +// String identifiers to be applied to segues on a storyboard +extern NSString* const SWSegueRearIdentifier; +extern NSString* const SWSegueFrontIdentifier; +extern NSString* const SWSegueRightIdentifier; + + // This will allow the class to be defined on a storyboard -#pragma mark - SWRevealViewControllerSegue +#pragma mark - SWRevealViewControllerSegueSetController Classes + +// Use this along with one of the segue identifiers to segue to the initial state +@interface SWRevealViewControllerSegueSetController : UIStoryboardSegue +@end -@interface SWRevealViewControllerSegue : UIStoryboardSegue -@property (strong) void(^performBlock)( SWRevealViewControllerSegue* segue, UIViewController* svc, UIViewController* dvc ); +#pragma mark - SWRevealViewControllerSeguePushController Classes +// Use this to push a view controller +@interface SWRevealViewControllerSeguePushController : UIStoryboardSegue @end +#pragma mark - SWRevealViewControllerSegue (Deprecated) + +@interface SWRevealViewControllerSegue : UIStoryboardSegue // DEPRECATED: USE SWRevealViewControllerSegueSetController instead +@property (nonatomic, strong) void(^performBlock)( SWRevealViewControllerSegue* segue, UIViewController* svc, UIViewController* dvc ); +@end \ No newline at end of file diff --git a/SWRevealViewController/SWRevealViewController.m b/SWRevealViewController/SWRevealViewController.m index b2bc370..5bf02a6 100755 --- a/SWRevealViewController/SWRevealViewController.m +++ b/SWRevealViewController/SWRevealViewController.m @@ -29,73 +29,73 @@ Early code inspired on a similar class by Philip Kluz (Philip.Kluz@zuui.org) #import "SWRevealViewController.h" -#pragma mark - SWDirectionPanGestureRecognizer - -typedef enum -{ - SWDirectionPanGestureRecognizerVertical, - SWDirectionPanGestureRecognizerHorizontal - -} SWDirectionPanGestureRecognizerDirection; - -@interface SWDirectionPanGestureRecognizer : UIPanGestureRecognizer - -@property (nonatomic, assign) SWDirectionPanGestureRecognizerDirection direction; - -@end - - -@implementation SWDirectionPanGestureRecognizer -{ - BOOL _dragging; - CGPoint _init; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ - [super touchesBegan:touches withEvent:event]; - - UITouch *touch = [touches anyObject]; - _init = [touch locationInView:self.view]; - _dragging = NO; -} - - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -{ - [super touchesMoved:touches withEvent:event]; - - if (self.state == UIGestureRecognizerStateFailed) - return; - - if ( _dragging ) - return; - - const int kDirectionPanThreshold = 5; - - UITouch *touch = [touches anyObject]; - CGPoint nowPoint = [touch locationInView:self.view]; - - CGFloat moveX = nowPoint.x - _init.x; - CGFloat moveY = nowPoint.y - _init.y; - - if (abs(moveX) > kDirectionPanThreshold) - { - if (_direction == SWDirectionPanGestureRecognizerHorizontal) - _dragging = YES; - else - self.state = UIGestureRecognizerStateFailed; - } - else if (abs(moveY) > kDirectionPanThreshold) - { - if (_direction == SWDirectionPanGestureRecognizerVertical) - _dragging = YES ; - else - self.state = UIGestureRecognizerStateFailed; - } -} - -@end +//#pragma mark - SWDirectionPanGestureRecognizer +// +//typedef enum +//{ +// SWDirectionPanGestureRecognizerVertical, +// SWDirectionPanGestureRecognizerHorizontal +// +//} SWDirectionPanGestureRecognizerDirection; +// +//@interface SWDirectionPanGestureRecognizer : UIPanGestureRecognizer +// +//@property (nonatomic, assign) SWDirectionPanGestureRecognizerDirection direction; +// +//@end +// +// +//@implementation SWDirectionPanGestureRecognizer +//{ +// BOOL _dragging; +// CGPoint _init; +//} +// +//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +//{ +// [super touchesBegan:touches withEvent:event]; +// +// UITouch *touch = [touches anyObject]; +// _init = [touch locationInView:self.view]; +// _dragging = NO; +//} +// +// +//- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +//{ +// [super touchesMoved:touches withEvent:event]; +// +// if (self.state == UIGestureRecognizerStateFailed) +// return; +// +// if ( _dragging ) +// return; +// +// const int kDirectionPanThreshold = 5; +// +// UITouch *touch = [touches anyObject]; +// CGPoint nowPoint = [touch locationInView:self.view]; +// +// CGFloat moveX = nowPoint.x - _init.x; +// CGFloat moveY = nowPoint.y - _init.y; +// +// if (abs(moveX) > kDirectionPanThreshold) +// { +// if (_direction == SWDirectionPanGestureRecognizerHorizontal) +// _dragging = YES; +// else +// self.state = UIGestureRecognizerStateFailed; +// } +// else if (abs(moveY) > kDirectionPanThreshold) +// { +// if (_direction == SWDirectionPanGestureRecognizerVertical) +// _dragging = YES ; +// else +// self.state = UIGestureRecognizerStateFailed; +// } +//} +// +//@end #pragma mark - StatusBar Helper Function @@ -593,79 +593,6 @@ - (void)_initDefaultProperties } -#pragma mark Storyboard support - -static NSString * const SWSegueRearIdentifier = @"sw_rear"; -static NSString * const SWSegueFrontIdentifier = @"sw_front"; -static NSString * const SWSegueRightIdentifier = @"sw_right"; - -- (void)prepareForSegue:(SWRevealViewControllerSegue *)segue sender:(id)sender -{ - // $ using a custom segue we can get access to the storyboard-loaded rear/front view controllers - // the trick is to define segues of type SWRevealViewControllerSegue on the storyboard - // connecting the SWRevealViewController to the desired front/rear controllers, - // and setting the identifiers to "sw_rear" and "sw_front" - - // $ these segues are invoked manually in the loadView method if a storyboard - // was used to instantiate the SWRevealViewController - - // $ none of this would be necessary if Apple exposed "relationship" segues for container view controllers. - - NSString *identifier = segue.identifier; - if ( [segue isKindOfClass:[SWRevealViewControllerSegue class]] && sender == nil ) - { - if ( [identifier isEqualToString:SWSegueRearIdentifier] ) - { - segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) - { - [self _setRearViewController:dvc animated:NO]; - }; - } - else if ( [identifier isEqualToString:SWSegueFrontIdentifier] ) - { - segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) - { - [self _setFrontViewController:dvc animated:NO]; - }; - } - else if ( [identifier isEqualToString:SWSegueRightIdentifier] ) - { - segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) - { - [self _setRightViewController:dvc animated:NO]; - }; - } - } -} - -// Load any defined front/rear controllers from the storyboard -// This method is intended to be overrided in case the default behavior will not meet your needs -- (void)loadStoryboardControllers -{ - if ( self.storyboard && _rearViewController == nil ) - { - //Try each segue separately so it doesn't break prematurely if either Rear or Right views are not used. - @try - { - [self performSegueWithIdentifier:SWSegueRearIdentifier sender:nil]; - } - @catch(NSException *exception) {} - - @try - { - [self performSegueWithIdentifier:SWSegueFrontIdentifier sender:nil]; - } - @catch(NSException *exception) {} - - @try - { - [self performSegueWithIdentifier:SWSegueRightIdentifier sender:nil]; - } - @catch(NSException *exception) {} - } -} - - #pragma mark - StatusBar - (UIViewController *)childViewControllerForStatusBarStyle @@ -685,6 +612,7 @@ - (UIViewController *)childViewControllerForStatusBarHidden return controller; } + #pragma mark - View lifecycle - (void)loadView @@ -758,14 +686,6 @@ - (NSUInteger)supportedInterfaceOrientations return [super supportedInterfaceOrientations]; } -//// Support for earlier than iOS 6.0 -//#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 -//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -//{ -// return YES; -//} -//#endif - #pragma mark - Public methods and property accessors @@ -900,10 +820,14 @@ - (UIPanGestureRecognizer*)panGestureRecognizer { if ( _panGestureRecognizer == nil ) { - SWDirectionPanGestureRecognizer *panRecognizer = - [[SWDirectionPanGestureRecognizer alloc] initWithTarget:self action:@selector(_handleRevealGesture:)]; +// SWDirectionPanGestureRecognizer *panRecognizer = +// [[SWDirectionPanGestureRecognizer alloc] initWithTarget:self action:@selector(_handleRevealGesture:)]; +// +// panRecognizer.direction = SWDirectionPanGestureRecognizerHorizontal; + + UIPanGestureRecognizer *panRecognizer = + [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(_handleRevealGesture:)]; - panRecognizer.direction = SWDirectionPanGestureRecognizerHorizontal; panRecognizer.delegate = self; [_contentView.frontView addGestureRecognizer:panRecognizer]; _panGestureRecognizer = panRecognizer ; @@ -929,13 +853,13 @@ - (UITapGestureRecognizer*)tapGestureRecognizer #pragma mark - Provided acction methods -- (void)revealToggle:(id)sender +- (IBAction)revealToggle:(id)sender { [self revealToggleAnimated:YES]; } -- (void)rightRevealToggle:(id)sender +- (IBAction)rightRevealToggle:(id)sender { [self rightRevealToggleAnimated:YES]; } @@ -959,6 +883,7 @@ - (void)_restoreUserInteraction [_contentView setDisableLayout:NO]; } + #pragma mark - PanGesture progress notification - (void)_notifyPanGestureBegan @@ -1113,12 +1038,17 @@ - (BOOL)_tapGestureShouldBegin - (BOOL)_panGestureShouldBegin { + // forbid gesture if the initial translation is not horizontal + UIView *recognizerView = _panGestureRecognizer.view; + CGPoint translation = [_panGestureRecognizer translationInView:recognizerView]; + if ( fabs(translation.y/translation.x) > 1 ) + return NO; + // forbid gesture if the following delegate is implemented and returns NO if ( [_delegate respondsToSelector:@selector(revealControllerPanGestureShouldBegin:)] ) if ( [_delegate revealControllerPanGestureShouldBegin:self] == NO ) return NO; - UIView *recognizerView = _panGestureRecognizer.view; CGFloat xLocation = [_panGestureRecognizer locationInView:recognizerView].x; CGFloat width = recognizerView.bounds.size.width; @@ -1354,7 +1284,7 @@ - (void)_dispatchSetRightViewController:(UIViewController *)newRightViewControll } -#pragma mark animated view controller deployment and layout +#pragma mark Animated view controller deployment and layout // Primitive method for view controller deployment and animated layout to the given position. - (void)_setFrontViewPosition:(FrontViewPosition)newPosition withDuration:(NSTimeInterval)duration @@ -1645,8 +1575,70 @@ - (void)_performTransitionToViewController:(UIViewController*)new operation:(SWR } -@end +#pragma mark Storyboard support +- (void)prepareForSegue:(SWRevealViewControllerSegue *)segue sender:(id)sender // TO REMOVE: DEPRECATED IMPLEMENTATION +{ + // This method is required for compatibility with SWRevealViewControllerSegue, now deprecated. + // It can be simply removed when using SWRevealViewControllerSegueSetController and SWRevealViewControlerSeguePushController + + NSString *identifier = segue.identifier; + if ( [segue isKindOfClass:[SWRevealViewControllerSegue class]] && sender == nil ) + { + if ( [identifier isEqualToString:SWSegueRearIdentifier] ) + { + segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) + { + [self _setRearViewController:dvc animated:NO]; + }; + } + else if ( [identifier isEqualToString:SWSegueFrontIdentifier] ) + { + segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) + { + [self _setFrontViewController:dvc animated:NO]; + }; + } + else if ( [identifier isEqualToString:SWSegueRightIdentifier] ) + { + segue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) + { + [self _setRightViewController:dvc animated:NO]; + }; + } + } +} + + +// Load any defined front/rear controllers from the storyboard +// This method is intended to be overrided in case the default behavior will not meet your needs +- (void)loadStoryboardControllers +{ + if ( self.storyboard && _rearViewController == nil ) + { + //Try each segue separately so it doesn't break prematurely if either Rear or Right views are not used. + @try + { + [self performSegueWithIdentifier:SWSegueRearIdentifier sender:nil]; + } + @catch(NSException *exception) {} + + @try + { + [self performSegueWithIdentifier:SWSegueFrontIdentifier sender:nil]; + } + @catch(NSException *exception) {} + + @try + { + [self performSegueWithIdentifier:SWSegueRightIdentifier sender:nil]; + } + @catch(NSException *exception) {} + } +} + + +@end #pragma mark - UIViewController(SWRevealViewController) Category @@ -1668,16 +1660,58 @@ - (SWRevealViewController*)revealViewController @end +#pragma mark - SWRevealViewControllerSegueSetController segue identifiers + +NSString * const SWSegueRearIdentifier = @"sw_rear"; +NSString * const SWSegueFrontIdentifier = @"sw_front"; +NSString * const SWSegueRightIdentifier = @"sw_right"; + + +#pragma mark - SWRevealViewControllerSegueSetController class + +@implementation SWRevealViewControllerSegueSetController + +- (void)perform +{ + NSString *identifier = self.identifier; + SWRevealViewController *rvc = self.sourceViewController; + UIViewController *dvc = self.destinationViewController; + + if ( [identifier isEqualToString:SWSegueFrontIdentifier] ) + [rvc _setFrontViewController:dvc animated:NO]; + + else if ( [identifier isEqualToString:SWSegueRearIdentifier] ) + [rvc _setRearViewController:dvc animated:NO]; + + else if ( [identifier isEqualToString:SWSegueRightIdentifier] ) + [rvc _setRightViewController:dvc animated:NO]; +} + +@end + + +#pragma mark - SWRevealViewControllerSeguePushController class + +@implementation SWRevealViewControllerSeguePushController + +- (void)perform +{ + SWRevealViewController *rvc = [self.sourceViewController revealViewController]; + UIViewController *dvc = self.destinationViewController; + [rvc pushFrontViewController:dvc animated:YES]; +} + +@end + + #pragma mark - SWRevealViewControllerSegue Class -@implementation SWRevealViewControllerSegue +@implementation SWRevealViewControllerSegue // DEPRECATED - (void)perform { - if ( _performBlock != nil ) - { + if ( _performBlock ) _performBlock( self, self.sourceViewController, self.destinationViewController ); - } } @end