mirror of
https://github.com/zhigang1992/ECSlidingViewController.git
synced 2026-03-29 00:18:36 +08:00
Simplify API and internals
This commit is contained in:
@@ -17,9 +17,6 @@
|
||||
ECSlidingViewController *slidingViewController = (ECSlidingViewController *)self.window.rootViewController;
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
|
||||
|
||||
slidingViewController.anchorRightRevealAmount = 280;
|
||||
slidingViewController.anchorLeftRevealAmount = 280;
|
||||
|
||||
slidingViewController.underLeftViewController = [storyboard instantiateViewControllerWithIdentifier:@"Menu"];
|
||||
slidingViewController.topViewController = [storyboard instantiateViewControllerWithIdentifier:@"FirstTop"];
|
||||
|
||||
|
||||
@@ -20,19 +20,20 @@
|
||||
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
|
||||
self.view.clipsToBounds = NO;
|
||||
|
||||
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
|
||||
[self.slidingViewController enablePanningInDirection:ECSlideLeft forView:self.view peekAmount:40.0f];
|
||||
[self.slidingViewController enablePanningInDirection:ECSlideRight forView:self.view peekAmount:40.0f];
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
|
||||
self.slidingViewController.underRightViewController = [storyboard instantiateViewControllerWithIdentifier:@"UnderRight"];
|
||||
}
|
||||
|
||||
- (IBAction)revealMenu:(id)sender
|
||||
{
|
||||
[self.slidingViewController anchorToRight];
|
||||
[self.slidingViewController slideInDirection:ECSlideRight peekAmount:40.0f onComplete:nil];
|
||||
}
|
||||
|
||||
- (IBAction)revealUnderRight:(id)sender
|
||||
{
|
||||
[self.slidingViewController anchorToLeft];
|
||||
[self.slidingViewController slideInDirection:ECSlideLeft peekAmount:40.0f onComplete:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -43,7 +43,10 @@
|
||||
NSString *identifier = [NSString stringWithFormat:@"%@Top", [self.menuItems objectAtIndex:indexPath.row]];
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
|
||||
UIViewController *newTopViewController = [storyboard instantiateViewControllerWithIdentifier:identifier];
|
||||
[self.slidingViewController slideOffToRightAndReplaceTopViewController:newTopViewController onComplete:^{
|
||||
[self.slidingViewController slideInDirection:ECSlideRight peekAmount:0.0f onComplete:^{
|
||||
CGRect frame = self.slidingViewController.topViewController.view.frame;
|
||||
self.slidingViewController.topViewController = newTopViewController;
|
||||
self.slidingViewController.topViewController.view.frame = frame;
|
||||
[self.slidingViewController reset];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -13,13 +13,12 @@
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
|
||||
self.slidingViewController.underRightViewController = nil;
|
||||
[self.slidingViewController enablePanningInDirection:ECSlideRight forView:self.view peekAmount:40.0f];
|
||||
}
|
||||
|
||||
- (IBAction)revealMenu:(id)sender
|
||||
{
|
||||
[self.slidingViewController anchorToRight];
|
||||
[self.slidingViewController slideInDirection:ECSlideRight peekAmount:40.0f onComplete:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
|
||||
[self.slidingViewController enablePanningInDirection:ECSlideLeft forView:self.view peekAmount:40.0f];
|
||||
[self.slidingViewController enablePanningInDirection:ECSlideRight forView:self.view peekAmount:40.0f];
|
||||
self.slidingViewController.underRightViewController = nil;
|
||||
}
|
||||
|
||||
- (IBAction)revealMenu:(id)sender
|
||||
{
|
||||
[self.slidingViewController anchorToRight];
|
||||
[self.slidingViewController slideInDirection:ECSlideRight peekAmount:40.0f onComplete:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
|
||||
{
|
||||
[self.slidingViewController slideOffToLeftOnComplete:nil];
|
||||
[self.slidingViewController slideInDirection:ECSlideLeft peekAmount:0.0f onComplete:nil];
|
||||
}
|
||||
|
||||
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
|
||||
{
|
||||
[self.slidingViewController anchorToLeft];
|
||||
[self.slidingViewController slideInDirection:ECSlideLeft peekAmount:40.0f onComplete:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,22 +9,20 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "UIImage+UIImage_ImageWithUIView.h"
|
||||
|
||||
typedef enum {
|
||||
ECSlideLeft,
|
||||
ECSlideRight
|
||||
} ECSlideDirection;
|
||||
|
||||
@interface ECSlidingViewController : UIViewController
|
||||
|
||||
@property (nonatomic, strong) UIViewController *underLeftViewController;
|
||||
@property (nonatomic, strong) UIViewController *underRightViewController;
|
||||
@property (nonatomic, strong) UIViewController *topViewController;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat anchorRightRevealAmount;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat anchorLeftRevealAmount;
|
||||
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
|
||||
|
||||
- (void)anchorToRight;
|
||||
- (void)anchorToLeft;
|
||||
- (void)slideInDirection:(ECSlideDirection)slideDirection peekAmount:(CGFloat)peekAmount onComplete:(void(^)())completeBlock;
|
||||
- (void)enablePanningInDirection:(ECSlideDirection)slideDirection forView:(UIView *)view peekAmount:(CGFloat)peekAmount;
|
||||
- (void)reset;
|
||||
- (void)slideOffToRightAndReplaceTopViewController:(UIViewController *)newTopViewController onComplete:(void(^)())completeBlock;
|
||||
- (void)slideOffToLeftAndReplaceTopViewController:(UIViewController *)newTopViewController onComplete:(void(^)())completeBlock;
|
||||
- (void)slideOffToRightOnComplete:(void(^)())completeBlock;
|
||||
- (void)slideOffToLeftOnComplete:(void(^)())completeBlock;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -10,23 +10,26 @@
|
||||
|
||||
@interface ECSlidingViewController()
|
||||
|
||||
@property (nonatomic, unsafe_unretained) CGFloat rightSidePeekAmount;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat leftSidePeekAmount;
|
||||
@property (nonatomic, strong) UIButton *topViewSnapshot;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *resetTapGesture;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat initialTouchPositionX;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat initialLeftEdgePosition;
|
||||
@property (nonatomic, unsafe_unretained) CGFloat initialHoizontalCenter;
|
||||
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *resetTapGesture;
|
||||
|
||||
- (NSUInteger)autoResizeToFillScreen;
|
||||
- (UIView *)topView;
|
||||
- (UIView *)underLeftView;
|
||||
- (UIView *)underRightView;
|
||||
- (void)updateTopViewLeftEdgePosition:(CGFloat)position;
|
||||
- (void)updateTopViewHorizontalCenterWithRecognizer:(UIPanGestureRecognizer *)recognizer;
|
||||
- (void)updateTopViewHorizontalCenter:(CGFloat)newHorizontalCenter;
|
||||
- (void)addTopViewSnapshot;
|
||||
- (void)removeTopViewSnapshot;
|
||||
- (CGFloat)screenWidth;
|
||||
- (CGFloat)screenWidthForOrientation:(UIInterfaceOrientation)orientation;
|
||||
- (BOOL)underLeftShowing;
|
||||
- (BOOL)underRightShowing;
|
||||
|
||||
- (void)underLeftWillAppear;
|
||||
- (void)underRightWillAppear;
|
||||
- (void)topDidReset;
|
||||
@@ -48,19 +51,26 @@
|
||||
@end
|
||||
|
||||
@implementation ECSlidingViewController
|
||||
|
||||
// public properties
|
||||
@synthesize underLeftViewController = _underLeftViewController;
|
||||
@synthesize underRightViewController = _underRightViewController;
|
||||
@synthesize topViewController = _topViewController;
|
||||
@synthesize anchorRightRevealAmount;
|
||||
@synthesize anchorLeftRevealAmount;
|
||||
|
||||
// category properties
|
||||
@synthesize leftSidePeekAmount;
|
||||
@synthesize rightSidePeekAmount;
|
||||
@synthesize topViewSnapshot;
|
||||
@synthesize resetTapGesture;
|
||||
@synthesize initialTouchPositionX;
|
||||
@synthesize initialLeftEdgePosition;
|
||||
@synthesize initialHoizontalCenter;
|
||||
@synthesize panGesture;
|
||||
@synthesize resetTapGesture;
|
||||
|
||||
- (void)setTopViewController:(UIViewController *)theTopViewController
|
||||
{
|
||||
self.leftSidePeekAmount = NSNotFound;
|
||||
self.rightSidePeekAmount = NSNotFound;
|
||||
|
||||
[self removeTopViewSnapshot];
|
||||
[_topViewController.view removeFromSuperview];
|
||||
[_topViewController removeFromParentViewController];
|
||||
@@ -114,7 +124,7 @@
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
self.resetTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reset)];
|
||||
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(updateTopViewLeftEdgePositionWithRecognizer:)];
|
||||
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(updateTopViewHorizontalCenterWithRecognizer:)];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
@@ -122,100 +132,73 @@
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
||||
- (void)updateTopViewLeftEdgePositionWithRecognizer:(UIPanGestureRecognizer *)recognizer
|
||||
- (void)updateTopViewHorizontalCenterWithRecognizer:(UIPanGestureRecognizer *)recognizer
|
||||
{
|
||||
CGPoint currentTouchPoint = [recognizer locationInView:self.view];
|
||||
CGFloat currentTouchPositionX = currentTouchPoint.x;
|
||||
|
||||
if (recognizer.state == UIGestureRecognizerStateBegan) {
|
||||
self.initialTouchPositionX = currentTouchPositionX;
|
||||
self.initialLeftEdgePosition = self.topView.frame.origin.x;
|
||||
self.initialHoizontalCenter = self.topView.center.x;
|
||||
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
|
||||
CGFloat newLeftEdge = self.initialLeftEdgePosition + currentTouchPositionX - self.initialTouchPositionX;
|
||||
CGFloat panAmount = self.initialTouchPositionX - currentTouchPositionX;
|
||||
CGFloat newCenterPosition = self.initialHoizontalCenter - panAmount;
|
||||
|
||||
if ((!self.underLeftViewController && newLeftEdge > 0) || (!self.underRightViewController && newLeftEdge < 0)) {
|
||||
newLeftEdge = 0;
|
||||
if ((newCenterPosition < self.view.center.x && self.leftSidePeekAmount == NSNotFound) || (newCenterPosition > self.view.center.x && self.rightSidePeekAmount == NSNotFound)) {
|
||||
newCenterPosition = self.view.center.x;
|
||||
}
|
||||
|
||||
[self updateTopViewLeftEdgePosition:newLeftEdge];
|
||||
[self updateTopViewHorizontalCenter:newCenterPosition];
|
||||
} else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) {
|
||||
CGPoint currentVelocityPoint = [recognizer velocityInView:self.view];
|
||||
CGFloat currentVelocityX = currentVelocityPoint.x;
|
||||
|
||||
if ([self underLeftShowing] && currentVelocityX > 100) {
|
||||
[self anchorToRight];
|
||||
[self slideInDirection:ECSlideRight peekAmount:self.rightSidePeekAmount onComplete:nil];
|
||||
} else if ([self underRightShowing] && currentVelocityX < 100) {
|
||||
[self anchorToLeft];
|
||||
[self slideInDirection:ECSlideLeft peekAmount:self.leftSidePeekAmount onComplete:nil];
|
||||
} else {
|
||||
[self reset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)anchorToRight
|
||||
- (void)slideInDirection:(ECSlideDirection)slideDirection peekAmount:(CGFloat)peekAmount onComplete:(void(^)())completeBlock;
|
||||
{
|
||||
CGFloat newCenter = self.topView.center.x;
|
||||
|
||||
if (slideDirection == ECSlideLeft) {
|
||||
newCenter = -self.screenWidth + self.view.center.x + peekAmount;
|
||||
} else if (slideDirection == ECSlideRight) {
|
||||
newCenter = self.screenWidth + self.view.center.x - peekAmount;
|
||||
}
|
||||
|
||||
[UIView animateWithDuration:0.25f animations:^{
|
||||
[self updateTopViewLeftEdgePosition:self.anchorRightRevealAmount];
|
||||
[self updateTopViewHorizontalCenter:newCenter];
|
||||
} completion:^(BOOL finished) {
|
||||
if (completeBlock) {
|
||||
completeBlock();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)anchorToLeft
|
||||
- (void)enablePanningInDirection:(ECSlideDirection)slideDirection forView:(UIView *)view peekAmount:(CGFloat)peekAmount
|
||||
{
|
||||
[UIView animateWithDuration:0.25f animations:^{
|
||||
[self updateTopViewLeftEdgePosition:-self.anchorLeftRevealAmount];
|
||||
}];
|
||||
if (slideDirection == ECSlideLeft) {
|
||||
self.leftSidePeekAmount = peekAmount;
|
||||
} else if (slideDirection == ECSlideRight) {
|
||||
self.rightSidePeekAmount = peekAmount;
|
||||
}
|
||||
|
||||
if (![[view gestureRecognizers] containsObject:self.panGesture]) {
|
||||
[view addGestureRecognizer:self.panGesture];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
[UIView animateWithDuration:0.25f animations:^{
|
||||
[self updateTopViewLeftEdgePosition:0];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)slideOffToRightAndReplaceTopViewController:(UIViewController *)newTopViewController onComplete:(void(^)())completeBlock;
|
||||
{
|
||||
[self slideOffToRightOnComplete:^{
|
||||
self.topViewController = newTopViewController;
|
||||
[self updateTopViewLeftEdgePosition:self.screenWidth];
|
||||
|
||||
if (completeBlock) {
|
||||
completeBlock();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)slideOffToLeftAndReplaceTopViewController:(UIViewController *)newTopViewController onComplete:(void(^)())completeBlock;
|
||||
{
|
||||
[self slideOffToLeftOnComplete:^{
|
||||
self.topViewController = newTopViewController;
|
||||
[self updateTopViewLeftEdgePosition:self.screenWidth];
|
||||
|
||||
if (completeBlock) {
|
||||
completeBlock();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)slideOffToRightOnComplete:(void(^)())completeBlock;
|
||||
{
|
||||
[UIView animateWithDuration:0.125f animations:^{
|
||||
[self updateTopViewLeftEdgePosition:self.screenWidth];
|
||||
} completion:^(BOOL finished) {
|
||||
if (completeBlock) {
|
||||
completeBlock();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)slideOffToLeftOnComplete:(void(^)())completeBlock;
|
||||
{
|
||||
[UIView animateWithDuration:0.125f animations:^{
|
||||
[self updateTopViewLeftEdgePosition:-self.screenWidth];
|
||||
} completion:^(BOOL finished) {
|
||||
if (completeBlock) {
|
||||
completeBlock();
|
||||
}
|
||||
[self updateTopViewHorizontalCenter:self.view.center.x];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -244,20 +227,20 @@
|
||||
return self.underRightViewController.view;
|
||||
}
|
||||
|
||||
- (void)updateTopViewLeftEdgePosition:(CGFloat)position
|
||||
- (void)updateTopViewHorizontalCenter:(CGFloat)newHorizontalCenter
|
||||
{
|
||||
CGRect frame = self.topView.frame;
|
||||
CGPoint center = self.topView.center;
|
||||
|
||||
if (frame.origin.x <= 0 && position > 0) {
|
||||
if (center.x <= self.view.center.x && newHorizontalCenter > self.view.center.x) {
|
||||
[self underLeftWillAppear];
|
||||
} else if (frame.origin.x >= 0 && position < 0) {
|
||||
} else if (center.x >= self.view.center.x && newHorizontalCenter < self.view.center.x) {
|
||||
[self underRightWillAppear];
|
||||
}
|
||||
|
||||
frame.origin.x = position;
|
||||
self.topView.frame = frame;
|
||||
center.x = newHorizontalCenter;
|
||||
self.topView.center = center;
|
||||
|
||||
if (position == 0) {
|
||||
if (newHorizontalCenter == self.view.center.x) {
|
||||
[self topDidReset];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user