自定义segue实现从左到右的滑动菜单

custom segue to achieve slide menu from left to right

刚接触动画,想写一个自定义segue实现从左到右滑出侧边菜单,覆盖home view,占半屏。

有一个自定义转接代码:

#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

我加了个变量看frame对不对,换frame就对了

但是我没有看到我的 "expected" 动画:sideBarVC.view.frame = animationFrame;

有人可以帮忙吗?谢谢

如果你想要一个从左到右的滑动动画,你首先要将动画视图的frame的原始X设置为负值,然后在动画块中,将原始x设置为0。诸如此类。

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];

使用你的代码我没有看到动画发生,因为 sideBarVC.view 被添加到动画的完成块中。到那时动画已经完成,并且 sideBarVC.view 添加为子视图并设置其框架。

结果我误解了这个位置。使用下面的代码可以实现动画,

但还是有一个问题,侧边栏菜单在屏幕上方的导航工具栏下面。有人知道怎么解决吗?

- (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;

    }];

为Swift3

         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
            }
        }