Wingzero
Wingzero

Reputation: 9754

custom segue to achieve slide menu from left to right

I am new to animation, and trying to write a custom segue to achieve slide out a side menu from left to right, overlay the home view, and occupy half of the screen.

segue from home view to side bar view

There is a custom segue code:

#import "CustomSegue.h"

@implementation CustomSegue

- (void)perform {
    UIViewController *contentVC = self.sourceViewController;
    UIViewController *sideBarVC = self.destinationViewController;
    CGRect sideFrame = sideBarVC.view.frame;
    [sideBarVC.view setFrame: CGRectMake(0, 0, 0, contentVC.view.frame.size.height)];
    CGRect animationFrame = contentVC.view.frame;
    sideFrame = sideBarVC.view.frame;
    animationFrame.size.width = contentVC.view.frame.size.width / 2;
    [UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:
     ^{
        sideBarVC.view.frame = animationFrame;
    }
                     completion:
     ^(BOOL finished) {
        sideBarVC.view.frame = animationFrame;
        contentVC.view.alpha = 0.5f;
        [[contentVC.view superview] addSubview:sideBarVC.view];
    }];

}

@end

I add some variable to see if the frame is correct, and it is correct when I change the frame.

But I don't see my "expected" animation: sideBarVC.view.frame = animationFrame;

Could some one help on this? Thanks.

Upvotes: 1

Views: 752

Answers (3)

Nikunj Damani
Nikunj Damani

Reputation: 753

For Swift 3

         override func perform() {
            let contentVC = self.sourceViewController;
            let sideBarVC = self.destinationViewController;

            var sideFrame = sideBarVC.view.frame

            sideBarVC.view.frame = CGRect(x: -(contentVC.view.frame.size.width), y: 0, width: contentVC.view.frame.size.width/2, height: contentVC.view.frame.size.height)

            sideFrame = sideFrame.offsetBy(dx: -1 * contentVC.view.frame.size.width, dy: 0)
            contentVC.view.superview?.addSubview(sideBarVC.view)

            UIView.animate(withDuration: 0.3) {
                sideBarVC.view.frame = sideFrame
                contentVC.view.alpha = 0.5
            }
        }

Upvotes: 0

Wingzero
Wingzero

Reputation: 9754

Tunred out I misunderstand the position. Using below code could achieve the animation,

but it still has one problem, the side bar menu is under navigation tool bar on top of the screen. Do anyone know how to solve it?

- (void)perform {
    UIViewController *contentVC = self.sourceViewController;
    UIViewController *sideBarVC = self.destinationViewController;
    CGRect sideFrame = sideBarVC.view.frame;
    [sideBarVC.view setFrame: CGRectMake(-(contentVC.view.frame.size.width), 0, contentVC.view.frame.size.width/2, contentVC.view.frame.size.height)];
    CGRect animationFrame = contentVC.view.frame;
    sideFrame = sideBarVC.view.frame;
    animationFrame.size.width = contentVC.view.frame.size.width / 2;
    sideBarVC.view.alpha = 0;
    [[[contentVC.view superview] window] addSubview:sideBarVC.view]; < -- this is important, not [superview addSubView]
    [UIView animateWithDuration:1
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
        sideBarVC.view.frame = animationFrame;
        sideBarVC.view.alpha = 1;
    }
                     completion:^(BOOL finished) {
        sideBarVC.view.alpha = 1;
        sideBarVC.view.frame = animationFrame;

    }];

but it still has one problem, the side bar menu is under navigation tool bar on top of the screen. Do anyone know how to solve it?

Upvotes: 0

gabbler
gabbler

Reputation: 13766

If you want to have a slide from left to right animation, you will firstly have to set the original X of animating view's frame to be a negative value, then in the animation block, set original x to be 0. Something like that.

sideFrame = sideBarVC.view.frame;

sideBarVC.view.frame = CGRectOffset(sideFrame, - contentVC.view.frame.size.width, 0);
[[contentVC.view superview] addSubview:sideBarVC.view];

[UIView animateWithDuration:0.3 animations:^{
    sideBarVC.view.frame = sideFrame;
    contentVC.view.alpha = 0.5f;
} completion:nil];

Using your code I don't see animation happens, because sideBarVC.view is added in the completion block of the animation. By then the animation has already finished, and sideBarVC.view is added as subview and its frame is set.

Upvotes: 1

Related Questions