Search code examples
swiftuiuikitmultitaskingipados

Set UIWindowScene.PresentationStyle on Scene?


I have a sample view that I'd love to render as a modal window, similar to the Mail message compose window in iPadOS 15:

WindowGroup("general.status", id: "create") { authorView  }
    .handlesExternalEvents(matching: ["starlight://create"])
    .commands { TextEditingCommands() }

With this setup via handlesExternalEvents(matching:Set<String>), I can get a window to open using openURL with a custom identifier, and I can see the modal option in the multitasking menu. However, when opening this window, it still appears as a full-screen scene. I noticed that in "Take your iPad apps to the next level (WWDC21)", you can set a presentation style for a window in UIKit by setting the presentation style to UIWindowScene.PresentationStyle.prominent. However, I can't find anything equivalent to this in SwiftUI. Is there a way I can do this in SwiftUI, or call some UIKit code to set the WindowGroup (or the authorView) with that activation condition?

I've initially asked this on the developer forums at https://developer.apple.com/forums/thread/700820 and both r/SwiftUI and r/iOSProgramming, but I'd like to cover my bases and ask here, too, if someone knows.


Solution

  • I've reached out to Apple via a TSI about this particular issue. As of the current release of SwiftUI, this isn't possible. They recommend I use the .sheet modifier instead and drop the split window capability. Otherwise, I can create a UISceneDelegate and use UIKit APIs directly:

    let options = UIWindowScene.ActivationRequestOptions()
    options.preferredPresentationStyle = .prominent
    let userActivity = NSUserActivity(activityType: SecondSceneDelegate.sceneUserActivityType)
    userActivity.targetContentIdentifier = SecondSceneDelegate.sceneUserActivityType
    
    UIApplication.shared.requestSceneSessionActivation(nil,
        userActivity: userActivity,
        options: options,
        errorHandler: nil)