1

I want to create a slide out menu from the right of my main view controller. However I want the slide out menu to appear on top of the main view and not push it to one side.

I've looked at ECSlidingViewController 2 and it allows sliding out from either side, however the slide out menus appear cut off on the exposed edges. It creates the effect of the top view controller moving left or right to reveal the hidden menu under it. I want it to appear that the hidden menu sliding out is going onto of the main view controller and that we can see its left edge so no content is cut off.

Is this at all possible and would ECSlidingViewController 2 work for this?

Edit

This is what I have tried:

To detect the touch started:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    BBAppDelegate *myAppDelegate = (BBAppDelegate*)[UIApplication sharedApplication].delegate;

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];
    NSArray *myViewArray = [[NSBundle mainBundle] loadNibNamed:@"FilterView" owner:self options:nil];
    self.filterView = myViewArray[0];


    [myAppDelegate.window addSubview:self.filterView];

    if (CGRectContainsPoint(self.filterView.frame, touchLocation)) {

        dragging = YES;
        oldX = touchLocation.x;
        oldY = touchLocation.y;
    }
}

And then dragging:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    if (dragging) {

        CGRect frame = self.filterView.frame;
        frame.origin.x = self.filterView.frame.origin.x + touchLocation.x;
        frame.origin.y =  self.filterView.frame.origin.y + touchLocation.y;
        self.filterView.frame = frame;
    }
}

However, when I start a touch, the filterView replaces all views and doesn't slide or animate in anyway. I though it was due to not providing a starting point - so I instated self.filterView like so:

self.filterView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 120, 564)];

However changing these values have no effect on the position / size of the view when its displayed.

Edit 2

Okay, I started a new project for testing and managed to get a view on screen to move around by following my touches.

I am using UIPanGestureRecognizer

Like so:

viewDidLoad

- (void)viewDidLoad

{ [super viewDidLoad];

NSArray *myViewArray = [[NSBundle mainBundle] loadNibNamed:@"View" owner:self options:nil];
UIView *myView = myViewArray[0];

self.filterView = myView;

self.filterView.frame = CGRectMake(100, 100, 200, 200);

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self
                                                                     action:@selector(dragging:)];
pan.delegate = self;

[self.filterView addGestureRecognizer:pan];


[self.view addSubview:self.filterView];

}

Then in the dragging method:

-(void)dragging:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateBegan)
        {
            NSLog(@"Received a pan gesture");
        self.panCoord = [gesture locationInView:gesture.view];


        }
    CGPoint newCoord = [gesture locationInView:gesture.view];
    float dX = newCoord.x-self.panCoord.x;


    gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX, gesture.view.frame.origin.y, gesture.view.frame.size.width, gesture.view.frame.size.height);
}

This allows the view to move horizontally only.

Almost there - what I am trying to figure out now is getting it to snap to a location when the user lifts their finger. And how to move this view when its start position is off screen.

Edit 3

Okay, so I wanted to control the speed and velocity of the view coming out onto screen. If the user swipes quickly, the view goes into place at the speed they swipe. If they swipe slowly, it goes into place slowly. However I also set the lowest time - so if they take a long time - it defaults to the min amount.

Here is the code:

{
   float start;
    float end;

    NSDate *methodStart;
    NSDate *methodEnd;

}



-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

methodStart = [NSDate date];

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:touch.view];

start = location.x;}


-(void)dragging:(UIPanGestureRecognizer *)gesture{

if(gesture.state == UIGestureRecognizerStateBegan)
    {

    self.panCoord = [gesture locationInView:gesture.view];


    }

CGPoint newCoord = [gesture locationInView:gesture.view];
float dX = newCoord.x-self.panCoord.x;





gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX, gesture.view.frame.origin.y, gesture.view.frame.size.width, gesture.view.frame.size.height);


if (gesture.state == UIGestureRecognizerStateEnded){

    methodEnd = [NSDate date];
    NSTimeInterval executionTime = [methodEnd timeIntervalSinceDate:methodStart];


    double time = executionTime;

    float distance = start - end;


    int distanceOverTime = distance / time;
    float veloticty = distanceOverTime / 100;

    double miniTimeToUse = 0.5;
    double newMinTime;
    if (time < miniTimeToUse){

        newMinTime =  miniTimeToUse;
    }else {
        newMinTime = time;
    }


    if (gesture.view.frame.origin.x+dX >= 180){

        [UIView animateWithDuration:newMinTime
                              delay:0
             usingSpringWithDamping:0.9
              initialSpringVelocity:veloticty
                            options:0
                         animations:^{

                             self.filterView.frame = CGRectMake(300, 100, 200, 200);

                         } completion:nil];

    }
    if (gesture.view.frame.origin.x+dX <= 181){

    [UIView animateWithDuration:newMinTime
    delay:0
    usingSpringWithDamping:0.9
    initialSpringVelocity:veloticty
    options:0
    animations:^{

        self.filterView.frame = CGRectMake(50, 100, 200, 200);

    } completion:nil];


    }
}

}

Now just to get it to work on pulling the view off from the side.

Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • Have you tried adding a UIView to the side of the screen and just animate that over your ViewController instead of using all kinds of shady 3rd party libs? This way you can shape and decorate the slide-over view just the way you want. – Totumus Maximus Mar 21 '14 at 09:20
  • I did think of that. However a it won't look right. If you have an iPhone - download the eBay app and then go into search and do a random search. Now, slide your finger from right to left - that view that comes out is how I would like mine to look like. A UIView will not cover the full screen including the tab bar at the bottom. Also, I would have to do a lot of animation and gesture code to control it. Thanks for the suggestion though. – Robert J. Clegg Mar 21 '14 at 09:24
  • 1
    It will cover the full screen when you add it to the application window (which will be managed properly ofc). And the animation would be 10 lines of code for both sliding it both ways. I'd give you an example, but I got it right at home (which I won't be at before another 6 hours). These libs kinda do it the same way, but I'd prefer control over the code instead of relying on libs or third-parties. – Totumus Maximus Mar 21 '14 at 09:30
  • I totally understand and agree that writing my own code would be the way to go and not relying too heavily on third party code. I'm still pretty new to this and haven't used the application window a lot. I'd really appreciate an example. I'll do some more research and testing in the mean time. If you could send me an example or even take me through it a little so I can learn more on this method, that would be cool.I don't mind waiting until you get time. Appreciate your help so far though. :) – Robert J. Clegg Mar 21 '14 at 09:35
  • @TotumusMaximus You were correct - adding the UIView to the AppDelegate window means it covers the screen as I need it to. I am now looking into how to control its position on screen with a swipe / drag gesture. Thanks again - hope I can make this work and get a deeper understanding of touch events and slide out menus. – Robert J. Clegg Mar 21 '14 at 15:37
  • I'm glad it worked out. Mind that you can use (Swipe)GestureRecognizers for an easy way to call methods. These can activate your animation. Or you can use a (touchesBegan/)touchesMoved function if you want even fancier stuff. – Totumus Maximus Mar 21 '14 at 15:58
  • Well I got as far as adding the view to the window. However when I try move it. It flickers and disappears. I'd like to control it with a drag event so it goes by touch and doesn't just animate on it's own out. Could you help me with a little code on getting it moving? Appreciate your help bud. – Robert J. Clegg Mar 21 '14 at 16:09
  • Can you show me what you have done so far? – Totumus Maximus Mar 21 '14 at 17:40
  • The trick is to make either the width of the view frame twice as large so it covers both the offscreen part as the on screen part. However keep the on screen part transparent! An alternative is placing the gesturerecognizer on the onscreen view instead of the view itself. This so that you don't actually drag the view but just make the movement and allow this to trigger a method that sets the frame to the difference in movement. – Totumus Maximus Mar 21 '14 at 21:32
  • Also concerning the snap. Use the following answer (http://stackoverflow.com/questions/6467638/detecting-pan-gesture-end) to fix this. Then check based on your last detected coordinate if your screen should snap offscreen or onscreen. You know the basic animation methods? (begin animation/endanimation blocks?) – Totumus Maximus Mar 21 '14 at 21:37
  • Well, I really wanted the view to slide out as slow or as fast as the user swipes and snap to certain positions. So I have been experimenting with my test project with awesome success! I will update my question with the new code - pretty happy with it! - can you take a look? then I will try your suggestion about pulling the view from off screen. – Robert J. Clegg Mar 21 '14 at 21:41
  • @TotumusMaximus - Updated my question - do you think I am doing a lot of extra work here for what I am trying to achieve? – Robert J. Clegg Mar 21 '14 at 21:53
  • It doesn't seem a whole lot actually. And you get the desired result right? I don't think optimising it to perfection is worthwhile in that case. – Totumus Maximus Mar 22 '14 at 08:09
  • No I haven't got the result I want as yet. The swipes are not always accurate and it seems a little flakey. Do you know of a better solution? – Robert J. Clegg Mar 22 '14 at 08:12
  • I'm sorry for the late response (busy weekends, eh?). Can you post me some images about the current behaviour you see? – Totumus Maximus Mar 24 '14 at 08:56
  • Sorry for only getting back now @TotumusMaximus - I was burning far too many hours trying to get it working nicely. I still can't get it to work like the eBay app. Might have to go a different route? – Robert J. Clegg Mar 26 '14 at 09:49
  • I actually found a very similar control at this link: https://www.cocoacontrols.com/controls/mvysidemenu Now just trying to see how it works and if I can get it to slide out from the right instead of the left. This is 95% to what I am looking for. I see the Google+ iOS app has the same menu I am looking for. – Robert J. Clegg Mar 26 '14 at 11:47

0 Answers0