When using a DocumentGroup in the SwiftUI Lifecycle,
the first view that the user sees is a UIDocumentBrowserViewController.
Because this isn't a SwiftUI view, and it's not passed to your app via the @Environment,
it's not easy to do anything special with the UI at that point
from a SwiftUI perspective
(eg put a button in the toolbar that can present a sheet).
This package sets up the bridging code needed
to respond to some simple life-cycle events
for the UIDocumentBrowserViewController,
so that simple UI modifications like this can be done.
Create a DocumentBrowserEventListener,
passing in one of the events available
(wasCreated, becameActive, or becameInactive).
In the callback, do whatever work you want to do.
The ideal place to do this would be in the init for a
UIApplicationDelegate marked with @UIApplicationDelegateAdaptor,
since it's called before the UIScene is created and it exists at the application level.
Note that, as far as SwiftUI is concerned,
the callback is being called outside the SwiftUI Lifecycle,
so you must interact with the view controller passed in
as a UIKit view controller.
You cannot access any @Environment variables
that are provided by the App struct, for example.
There's also an extension on UIDocumentBrowserViewController that simplifies the process of adding a toolbar button to it. Just call addLeadingToolbarItem(), passing in a UIBarButtonItem and a callback for the work that you would like to do. The callback gives you back the UIDocumentBrowserViewController. There are defaults for most options you would want to change and an override that lets you just pass in a SF Symbols system image name.
The following adds a toolbar button to the UIDocumentBrowserViewController that brings up a sheet containing a new SwiftUI view
final class AppDelegate: NSObject, UIApplicationDelegate {
let listener: DocumentBrowserEventListener
override init() {
self.listener = DocumentBrowserEventListener(.wasCreated) { documentBrowserViewController in
documentBrowserViewController.addToolbarItem(systemImageName: "scribble") { browser in
let exampleView = UIHostingController(rootView:
Text("Hello, World!")
)
browser.present(exampleView, animated: true)
}
}
super.init()
}
}This package has only been tested against iOS 16, and has not been tested against the new iOS 17 beta as of 6/10/23.
Questions or comments can be sent to me at my contact page.