When you're using the Coordinator pattern in a SwiftUI project, you'll find yourself sometimes wanting to preview the initial start of a "flow" of screens. But that's quite a bit of work because inside the coordinator, some boilerplate code needs to be present, to wrap the SwiftUI view in a UIHostingController.
This bit of code is useful to plunk in the utilities folder of your project, and use in the preview section of your SwiftUI view.
private class PreviewViewController: UIViewController { private let coordinator: NavigationControllerCoordinator
init(coordinator: NavigationControllerCoordinator) { self.coordinator = coordinator super.init(nibName: nil, bundle: nil) }
required init?(coder: NSCoder) { fatalError() }
override func viewDidLoad() { guard let navigationController = self.navigationController as? NavigationController else { return } title = "Preview"
var configuration = UIButton.Configuration.filled() configuration.title = "Start" self.view = UIButton(configuration: configuration, primaryAction: UIAction(handler: {_ in navigationController.present(self.coordinator.navigationController, animated: true) self.coordinator.start() })) } }
struct PreviewCoordinator: UIViewControllerRepresentable { let coordinator: NavigationControllerCoordinator
typealias UIViewControllerType = NavigationController
func makeUIViewController(context: Context) -> NavigationController { let viewController = PreviewViewController(coordinator: coordinator) return NavigationController(rootViewController: viewController) }
func updateUIViewController(_ uiViewController: NavigationController, context: Context) {} }
Use as follows;
struct NetworkScanQRView_Previews: PreviewProvider { static var previews: some View { PreviewCoordinator(coordinator: NetworkScanQRCoordinator.mocked) } }