Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android-like Navigation Drawer for iOS? [closed]

I'm looking for a way to implement in iOS something that works as closely as possible to the Android Navigation Drawer.

That's basically a menu panel that slides in from the left and over the current view.

I've looked at using ECSlidingViewController, MMDrawerController, etc. but I'd really want a drawer that appears on top of the current view, not like the Facebook app where the current view slides to reveal a menu underneath.

How can I implement my desired functionality?

like image 520
Mirko N. Avatar asked Oct 29 '13 16:10

Mirko N.


People also ask

What is DrawerLayout?

DrawerLayout acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from one or both vertical edges of the window.

What is ActionBarDrawerToggle?

public class ActionBarDrawerToggle implements DrawerLayout.DrawerListener. This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.


1 Answers

You would need a SlideOverViewController that has a table view with width as much as you want to overlap, set the background color of the view as clear color(to achieve transparency).

in your MainViewController, initialize and add your SlideOverViewController.

    self.slideOverViewController = [[SlideOverViewController alloc] init];
    self.slideOverViewController.view.frame = CGRectMake(-self.myNavigationController.view.frame.size.width, 0, self.myNavigationController.view.frame.size.width, self.view.frame.size.height);
    self.slideOverViewController.delegate = self;

To activate your slideOverMenu use:

    [self.slideOverViewController.view setHidden:NO];

    [self.view addSubview:self.slideOverViewController.view];

    [UIView animateWithDuration:kMenuAnimationDuration animations:^{

    self.slideOverViewController.view.frame = CGRectMake(0, 0, self.slideOverViewController.view.frame.size.width, self.slideOverViewController.view.frame.size.height);

    [UIView animateWithDuration:kMenuAnimationDuration animations:^{


    }completion:^(BOOL finished){

    }];

}completion:^(BOOL finished){
    self.mainMenuDisplay = YES;
}];

To hide the menu use:

        [UIView animateWithDuration:kMenuAnimationDuration animations:^{

        self.slideOverViewController.view.frame = CGRectMake(-self.myNavigationController.view.frame.size.width - 80, 0, self.myNavigationController.view.frame.size.width, self.myNavigationController.view.frame.size.height);

    }completion:^(BOOL finished){

        self.mainMenuDisplay = NO;
        [self.slideOverViewController.view setHidden:YES];
    }];

In you SLideOverViewController,

add gestureRecognizers:

    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGestures:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];



  - (void) handlePanGestures : (UIPanGestureRecognizer *) sender
{
if (self.view.frame.origin.x > 0) {
    return;
}

[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];

if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
    self.firstX = [[sender view] center].x;
    self.firstY = [[sender view] center].y;
}

translatedPoint = CGPointMake(self.firstX+translatedPoint.x, self.firstY);

if (translatedPoint.x > self.view.frame.size.width/2) {
    self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    return;
}

[[sender view] setCenter:translatedPoint];

if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded || [sender state] == UIGestureRecognizerStateCancelled || [sender state] == UIGestureRecognizerStateFailed) {

    CGFloat velocityX = (0.2*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);
    CGFloat finalX = translatedPoint.x + velocityX;
    CGFloat finalY = self.firstY;

    if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
        if (finalX < 0) {
            //finalX = 0;
        } else if (finalX > 768) {
            //finalX = 768;
        }

        if (finalY < 0) {
            finalY = 0;
        } else if (finalY > 1024) {
            finalY = 1024;
        }
    } else {
        if (finalX < 0) {
            //finalX = 0;
        } else if (finalX > 1024) {
            //finalX = 768;
        }

        if (finalY < 0) {
            finalY = 0;
        } else if (finalY > 768) {
            finalY = 1024;
        }
    }

    CGFloat animationDuration = (ABS(velocityX)*.0002)+.2;

    [self animateToPoint:finalX yPos:finalY withAnimationDuration:animationDuration];
}
}
}
}

- (void) animateToPoint : (CGFloat) finalX yPos : (CGFloat) finalY withAnimationDuration : (CGFloat) animationDuration {
if (self.view.frame.origin.x < -90) {
    [self handleCloseSlidingMenuViewController];

} else {
    [self handleShowSlidingMenuView : finalX yPos:finalY withAnimationDuration:animationDuration];
}}

- (void) handleShowSlidingMenuView : (CGFloat) finalX
                          yPos : (CGFloat) finalY
         withAnimationDuration : (CGFloat) animationDuration{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidFinish)];
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];}
like image 191
ManicMonkOnMac Avatar answered Oct 07 '22 19:10

ManicMonkOnMac