【问题标题】:Change RootViewcontroller with the Push Transition effect使用 Push Transition 效果更改 RootViewcontroller
【发布时间】:2014-06-23 09:51:01
【问题描述】:

在我的 iOS 应用程序中,我需要更改应用程序之间的窗口的 rootviewController。所以当我动态更改我的 rootviewcontroller 时,它会在更改之前轻弹视图。但是我想要的是在 rootviewcontroller 更改时提供平滑过渡.

我尝试过以下方法,但不是我想要的过渡。

[UIView transitionWithView:self.window
                      duration:.8
                       options:UIViewAnimationOptionTransitionCurlUp
                    animations:^{

                        self.window.rootViewController = tabBarControllerMain;
    [self.window makeKeyAndVisible];
                    }
                    completion:NULL];

我想要特定的过渡,例如导航控制器 pushview 过渡。

任何机构都可以告诉我如何实现这一目标吗?

【问题讨论】:

    标签: ios iphone objective-c uiviewanimationtransition


    【解决方案1】:

    根据 Hardik Darji 的回答,我创建了 UIWindow 扩展,以将 rootViewController 与可配置的动画类型交换,模拟系统动画 - 推送、弹出、呈现和关闭。

    斯威夫特 3.

    public enum SwapRootVCAnimationType {
        case push
        case pop
        case present
        case dismiss
    }
    
    
    extension UIWindow {
    public func swapRootViewControllerWithAnimation(newViewController:UIViewController, animationType:SwapRootVCAnimationType, completion: (() -> ())? = nil)
    {
        guard let currentViewController = rootViewController else {
            return
        }
    
        let width = currentViewController.view.frame.size.width;
        let height = currentViewController.view.frame.size.height;
    
        var newVCStartAnimationFrame: CGRect?
        var currentVCEndAnimationFrame:CGRect?
    
        var newVCAnimated = true
    
        switch animationType
        {
        case .push:
            newVCStartAnimationFrame = CGRect(x: width, y: 0, width: width, height: height)
            currentVCEndAnimationFrame = CGRect(x: 0 - width/4, y: 0, width: width, height: height)
        case .pop:
            currentVCEndAnimationFrame = CGRect(x: width, y: 0, width: width, height: height)
            newVCStartAnimationFrame = CGRect(x: 0 - width/4, y: 0, width: width, height: height)
            newVCAnimated = false
        case .present:
            newVCStartAnimationFrame = CGRect(x: 0, y: height, width: width, height: height)
        case .dismiss:
            currentVCEndAnimationFrame = CGRect(x: 0, y: height, width: width, height: height)
            newVCAnimated = false
        }
    
        newViewController.view.frame = newVCStartAnimationFrame ?? CGRect(x: 0, y: 0, width: width, height: height)
    
        addSubview(newViewController.view)
    
        if !newVCAnimated {
            bringSubview(toFront: currentViewController.view)
        }
    
        UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
            if let currentVCEndAnimationFrame = currentVCEndAnimationFrame {
                currentViewController.view.frame = currentVCEndAnimationFrame
            }
    
            newViewController.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
        }, completion: { finish in
            self.rootViewController = newViewController
            completion?()
        })
    
        makeKeyAndVisible()
    }
    

    }

    【讨论】:

    • 完美,但对于 Swift 3 建议在枚举中使用低寄存器
    • 我想我发现了一个小错误:viewWillAppear inside newViewController call两次
    • 确实有个小bug,两次调用viewWillAppearviewDidAppear
    【解决方案2】:

    Based on this Apple's documentation

    UIViewController *viewControllerToBeShown=[[UIViewController alloc]init];
    
    //viewControllerToBeShown.view.frame = self.view.frame;
    
    viewControllerToBeShown.view.backgroundColor = [UIColor orangeColor];
    
    
    
    AppDelegateClass *yourAppDelegate  =(AppDelegateClass*)[UIApplication sharedApplication].delegate;
    
    
    UIView *myView1 = yourAppDelegate.window.rootViewController.view;
    
    UIView *myView2 = viewControllerToBeShown.view;
    
    myView2.frame = yourAppDelegate.window.bounds;
    
    
    [yourAppDelegate.window addSubview:myView2];
    
    
    CATransition* transition = [CATransition animation];
    transition.startProgress = 0;
    transition.endProgress = 1.0;
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromRight;
    transition.duration = 5.0;
    
    // Add the transition animation to both layers
    [myView1.layer addAnimation:transition forKey:@"transition"];
    [myView2.layer addAnimation:transition forKey:@"transition"];
    
    myView1.hidden = YES;
    myView2.hidden = NO;
    
    
    yourAppDelegate.window.rootViewController = viewControllerToBeShown;
    

    斯威夫特

            guard let appDelegate = UIApplication.shared.delegate,
                let appDelegateWindow = appDelegate.window,
                let appDelegateView = window.rootViewController?.view,
                let viewContollersView = viewController.view else {
                return
            }
            viewContollersView.frame = (appDelegateWindow?.bounds)!
            appDelegate.window??.addSubview(viewContollersView)
            let transition = CATransition()
            transition.startProgress = 0
            transition.endProgress = 1.0
            transition.type = kCATransitionPush
            transition.subtype = kCATransitionFromRight
            transition.duration = 0.35
            appDelegateView.layer.add(transition, forKey: "transition")
            viewContollersView.layer.add(transition, forKey: "transition")
            appDelegateView.isHidden = true
            viewContollersView.isHidden = false
            appDelegateWindow?.rootViewController = viewController
    

    【讨论】:

    • 这行得通,但是有没有办法让以前的视图控制器不变成黑色?一旦动画开始,我执行代码的视图控制器就会变黑。
    • 在 Swift 中,检查这个答案...它的工作 stackoverflow.com/a/35224877/1000906
    • 这看起来不像 UINavigationController 中的过渡,你必须使用假 vc
    【解决方案3】:

    这是 Swift 中的代码,用于在 rootviewcontroller 中制作 Push 和 Pop 动画。

    //Declare enum
    enum AnimationType{
            case ANIMATE_RIGHT
            case ANIMATE_LEFT
            case ANIMATE_UP
            case ANIMATE_DOWN
        }
    // Create Function...
    
        func showViewControllerWith(newViewController:UIViewController, usingAnimation animationType:AnimationType)
    {
    
        let currentViewController = UIApplication.sharedApplication().delegate?.window??.rootViewController
        let width = currentViewController?.view.frame.size.width;
        let height = currentViewController?.view.frame.size.height;
    
        var previousFrame:CGRect?
        var nextFrame:CGRect?
    
        switch animationType
        {
            case .ANIMATE_LEFT:
                previousFrame = CGRectMake(width!-1, 0.0, width!, height!)
                nextFrame = CGRectMake(-width!, 0.0, width!, height!);
            case .ANIMATE_RIGHT:
                previousFrame = CGRectMake(-width!+1, 0.0, width!, height!);
                nextFrame = CGRectMake(width!, 0.0, width!, height!);
            case .ANIMATE_UP:
                previousFrame = CGRectMake(0.0, height!-1, width!, height!);
                nextFrame = CGRectMake(0.0, -height!+1, width!, height!);
            case .ANIMATE_DOWN:
                previousFrame = CGRectMake(0.0, -height!+1, width!, height!);
                nextFrame = CGRectMake(0.0, height!-1, width!, height!);
        }
    
        newViewController.view.frame = previousFrame!
        UIApplication.sharedApplication().delegate?.window??.addSubview(newViewController.view)
        UIView.animateWithDuration(0.33,
            animations: { () -> Void in
            newViewController.view.frame = (currentViewController?.view.frame)!
                currentViewController?.view.frame = nextFrame!
    
            })
            { (fihish:Bool) -> Void in
                UIApplication.sharedApplication().delegate?.window??.rootViewController = newViewController
            }
    }
    
    
    // call the func for ANIMATE_LEFT or ANIMATE_RIGHT etc
    
         self.showViewControllerWith(rootViewController, usingAnimation: AnimationType.ANIMATE_LEFT)
    

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 2012-03-25
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      相关资源
      最近更新 更多