viewWillTransition not called since change to UISceneDelegate

Since changing our app to the new UISceneDelegate architecture, we see the problem that viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)is not called on our ViewControllers anymore. Even when I remove everything which is not needed and just create a UIWindow and one UIViewController in scene(UIScene, willConnectTo: UISceneSession, options: UIScene.ConnectionOptions) it doesn't work.

I created a new clean project where it works without problems and checked how the stack trace looks:

  1. 0x0000000102117320 in ViewController.viewWillTransition(to:with:) at ViewController.swift:20
  2. 0x000000010211766c in @objc ViewController.viewWillTransition(to:with:) ()
  3. 0x0000000184673664 in +[UIViewController _performWithoutDeferringTransitionsAllowingAnimation:actions:] ()
  4. 0x000000018486247c in -[UIViewController(AdaptiveSizing_Internal) _window:viewWillTransitionToSize:withTransitionCoordinator:] ()
  5. 0x00000001846f5788 in __59-[UIWindow _rotateToBounds:withAnimator:transitionContext:]_block_invoke ()
  6. 0x0000000184621064 in +[UIView(Animation) performWithoutAnimation:] ()
  7. 0x0000000184ac2534 in -[UIWindow _rotateToBounds:withAnimator:transitionContext:] ()
  8. 0x000000018494a6b8 in -[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:] ()
  9. 0x0000000184573ee4 in -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] ()
  10. 0x0000000184b24b84 in -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] ()

I created some symbolic breakpoints in the broken project and noticed that it is working until step 5, but apparently something is preventing [UIViewController(AdaptiveSizing_Internal) _window:viewWillTransitionToSize:withTransitionCoordinator:] from being called.

Did anyone have a similar problem or an idea what could cause this problem?

I tested on a project with SceneDelegate.

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        
        super.viewWillTransition(to: size, with: coordinator)
        // Some stuff
        print(#function)
    }

viewWillTransition gets called when I rotate screen, as log shows:

viewWillTransition(to:with:)

Please show code of:

  • SceneDelegate
  • AppDelegate

and check you have correctly defined the SceneManifest in info.plist

Thanks for your reply!

This is our scene configuration:

	<dict>
		<key>UIApplicationSupportsMultipleScenes</key>
		<false/>
		<key>UISceneConfigurations</key>
		<dict>
			<key>UIWindowSceneSessionRoleApplication</key>
			<array>
				<dict>
					<key>UISceneConfigurationName</key>
					<string>Default Configuration</string>
					<key>UISceneDelegateClassName</key>
					<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
				</dict>
				<dict>
					<key>UISceneConfigurationName</key>
					<string>Stub Configuration</string>
					<key>UISceneDelegateClassName</key>
					<string>$(PRODUCT_MODULE_NAME).StubSceneDelegate</string>
				</dict>
			</array>
		</dict>
	</dict>

This is from our AppDelegate:

        UISceneConfiguration(name: "Default Configuration", sessionRole: .windowApplication)
    }

And this from the SceneDelegate:

        guard let windowScene = scene as? UIWindowScene else { return }

        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = TestViewController()
        self.window = window
        window.makeKeyAndVisible()

So I thinks this is very straightforward. It also works for me in another project without problems.

Not sure this matters, but when I compare to info.plist in a test project:

  • I have an additional UISceneStoryboardFile : Main, after UISceneDelegateClassName
  • You have 2 UISceneConfigurationName. Why ? I note that you have set UIApplicationSupportsMultipleScenes as false

AppDelegate is different as well:

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

In which func is code of SceneDelegate ? Do you use a storyboard ?

For everyone who is interested in this problem, here ist the solution:

We didn’t implement the method application(_:didFinishLaunchingWithOptions:) inside our AppDelegate. This somehow caused the app to not call viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) inside our ViewControllers. After we changed our app to using a SceneDelegate we didn’t need the method in the AppDelegate anymore, so we removed it. It is also declared as optional in the documentation. So I think this should not have such an effect on the app, but at least it works now again.

viewWillTransition not called since change to UISceneDelegate
 
 
Q