iosswiftuiviewanimationuiscenedelegate

RootViewController transition effect does not work


    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let protectionVC = storyboard.instantiateViewController(identifier: "PrivacyProtectionViewController")
    
    guard let windowScene = self.window?.windowScene else {
        return
    }
    
    privacyProtectionWindow = UIWindow(windowScene: windowScene)
    privacyProtectionWindow?.rootViewController = protectionVC
    UIView.transition(with: privacyProtectionWindow!, duration: 1.2, options: .transitionCrossDissolve, animations: nil, completion: nil)
    privacyProtectionWindow?.windowLevel = .alert + 1
    privacyProtectionWindow?.makeKeyAndVisible()

When I put this to sceneWillResignActive function in SceneDelegate.swift, it does not affect my transition style at all.

Do you have any idea why it does not work?!


Solution

  • The UIView.transition method will not work because you are animating the the window and not the controller's view which is being viewed on screen. Your animation duration (1.2 seconds) is also too long.

    When the user resigns from the current scene, the iOS animations occurs faster than 1 second. You might see it when switching between apps, but when moving to the home screen the animation occurs almost instantly.

    With all these considerations, you might be able to get the desired result with the following code.

    privacyProtectionWindow = UIWindow(windowScene: windowScene)
    privacyProtectionWindow?.rootViewController = protectionVC
    
    privacyProtectionWindow?.windowLevel = UIWindow.Level.alert
    privacyProtectionWindow?.makeKeyAndVisible()
    
    // New animation code
    protectionVC.view.alpha = 0.0
    UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseOut]) {
        protectionVC.view.alpha = 1.0
    }
    

    Also, for additional smoothness you can add animation when the scene becomes active again.

    func sceneDidBecomeActive(_ scene: UIScene) {
        UIView.animate(withDuration: 0.2) {
            self.privacyProtectionWindow?.rootViewController!.view.alpha = 0.0
        } completion: { (completed) in
            if completed{
                self.privacyProtectionWindow = nil
                self.window?.makeKeyAndVisible()
            }
        }
    }
    

    The animation of alpha values change UIView opacity. It will give you the effect you are going for with the UIView.transition method.