用动画交换rootViewController?

Chr*_*sen 54 xcode uiviewanimation rootview swift swift3

我试图用标签栏交换到另一个根视图控制器; 通过app委托,我想添加过渡动画.默认情况下,它只显示没有任何动画的视图.

let tabBar = self.instantiateViewController(storyBoard: "Main", viewControllerID: "MainTabbar")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.main.bounds)
appDelegate.window?.rootViewController = tabBar
appDelegate.window?.makeKeyAndVisible()
Run Code Online (Sandbox Code Playgroud)

这就是我交换到另一个rootview控制器的方式.

d.f*_*ber 145

我评估UIView.transition(with: view)rootViewController前一段时间,并最终使用这样的:(可惜不记得为什么)

guard let window = UIApplication.shared.keyWindow else {
    return
}

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabbar")

// Set the new rootViewController of the window.
// Calling "UIView.transition" below will animate the swap.
window.rootViewController = vc

// A mask of options indicating how you want to perform the animations.
let options: UIView.AnimationOptions = .transitionCrossDissolve

// The duration of the transition animation, measured in seconds.
let duration: TimeInterval = 0.3

// Creates a transition animation.
// Though `animations` is optional, the documentation tells us that it must not be nil. ¯\_(?)_/¯
UIView.transition(with: window, duration: duration, options: options, animations: {}, completion:
{ completed in
    // maybe do something on completion here
})
Run Code Online (Sandbox Code Playgroud)


Muh*_*aig 14

替代解决方案:

let stb = UIStoryboard(name: "YOUR_STORYBOARD_NAME", bundle: nil)
let rootVC = stb.instantiateViewController(withIdentifier: "YOUR_TABBAR_VIEWCONTROLLER_NAME")
let snapshot = (UIApplication.shared.keyWindow?.snapshotView(afterScreenUpdates: true))!
rootVC.view.addSubview(snapshot)

UIApplication.shared.keyWindow?.rootViewController = rootVC
UIView.transition(with: snapshot, 
                  duration: 0.4,
                  options: .transitionCrossDissolve,
                  animations: { 
                      snapshot.layer.opacity = 0
                  },
                  completion: { status in 
                      snapshot.removeFromSuperview()
                  })
Run Code Online (Sandbox Code Playgroud)


mat*_*att 10

我试图交换到另一个根视图控制器...我想添加过渡动画

我有一个应用程序执行此操作:它使用动画更改根视图控制器(它称为Albumen).

但我的应用实际上并没有真正改变根视图控制器.根视图控制器是一个永远不会更改的自定义容器视图控制器.它的视图从未见过,也没有任何功能.它唯一的工作就是成为变化发生的地方:它将一个子视图控制器换成另一个 - 因此过渡动画可以工作.

换句话说,您将一个视图控制器添加到视图控制器层次结构中,就在层次结构的顶部,整个问题得到了整齐和正确的解决.


JPe*_*ric 8

试试这个:

UIView.transition(from: appdelegate.window.rootViewController!.view, to: tabbar.view, duration: 0.6, options: [.transitionCrossDissolve], completion: {
    _ in
    appdelegate.window.rootViewController = tabbar
})
Run Code Online (Sandbox Code Playgroud)


Wii*_*ard 6

斯威夫特4

将功能粘贴到AppDelegate

func setRootViewController(_ vc: UIViewController, animated: Bool = true) {
    guard animated, let window = self.window else {
        self.window?.rootViewController = vc
        self.window?.makeKeyAndVisible()
        return
    }

    window.rootViewController = vc
    window.makeKeyAndVisible()
    UIView.transition(with: window,
                      duration: 0.3,
                      options: .transitionCrossDissolve,
                      animations: nil,
                      completion: nil)
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*kyi 6

更新了 Swift 5.3 版本:

    let foregroundedScenes = UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }
    let window = foregroundedScenes.map { $0 as? UIWindowScene }.compactMap { $0 }.first?.windows.filter { $0.isKeyWindow }.first
    
    guard let uWindow = window else { return }

    uWindow.rootViewController = customTabBarController
    UIView.transition(with: uWindow, duration: 0.3, options: [.transitionCrossDissolve], animations: {}, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)