Skip to content

Instantly share code, notes, and snippets.

@yosshi4486
Last active July 22, 2023 08:34
Show Gist options
  • Save yosshi4486/20f48789fb117a2e907658ed384a35a8 to your computer and use it in GitHub Desktop.
Save yosshi4486/20f48789fb117a2e907658ed384a35a8 to your computer and use it in GitHub Desktop.
An UIViewControllerRepresentable wrapper of UISplitViewController
/// UIKit製のUISplitViewController.
struct UIKitSplitView<Primary, Secondary>: UIViewControllerRepresentable where Primary : View, Secondary : View {
typealias UIViewControllerType = UISplitViewController
/// プライマリPaneのビューを生成するクロージャ
var primary: () -> Primary
/// セカンダリPaneのビューを生成するクロージャ
var secondary: () -> Secondary
var splitViewController: UISplitViewController
var primaryHostingViewController: UIHostingController<Primary>
var secondaryHostingViewController: UIHostingController<Secondary>
init(@ViewBuilder primary: @escaping () -> Primary, @ViewBuilder secondary: @escaping () -> Secondary) {
self.primary = primary
self.secondary = secondary
self.splitViewController = .init(style: .doubleColumn)
self.primaryHostingViewController = .init(rootView: primary())
self.secondaryHostingViewController = .init(rootView: secondary())
}
func makeUIViewController(context: Context) -> UISplitViewController {
// Examples of customizations
splitViewController.displayModeButtonVisibility = .never
splitViewController.preferredSplitBehavior = .tile
splitViewController.preferredDisplayMode = .oneBesideSecondary
splitViewController.preferredPrimaryColumnWidth = 400
splitViewController.minimumPrimaryColumnWidth = 400
splitViewController.maximumPrimaryColumnWidth = 480
splitViewController.delegate = context.coordinator
let primaryNavigationController = UINavigationController(rootViewController: primaryHostingViewController)
primaryNavigationController.navigationBar.prefersLargeTitles = true
primaryNavigationController.isToolbarHidden = false
primaryNavigationController.navigationItem.largeTitleDisplayMode = .automatic
primaryHostingViewController.navigationItem.title = String(localized: "TitleYouWant")
secondaryHostingViewController.navigationItem.largeTitleDisplayMode = .never
secondaryHostingViewController.navigationItem.title = String(localized: "TitleYouWant")
splitViewController.setViewController(primaryNavigationController, for: .primary)
splitViewController.setViewController(secondaryHostingViewController, for: .secondary)
return splitViewController
}
func updateUIViewController(_ uiViewController: UISplitViewController, context: Context) { }
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UISplitViewControllerDelegate {
var owner: UIKitSplitView<Primary, Secondary>
init(_ owner: UIKitSplitView<Primary, Secondary>) {
self.owner = owner
super.init()
// Post notifications when your primary tableview changes its selection.
NotificationCenter.default.addObserver(self, selector: #selector(showSecondary), name: .primarySelectionDidChangeNotification, object: nil)
}
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
return .primary
}
@objc func showSecondary(_ sender: Any?) {
owner.secondaryHostingViewController.rootView = owner.secondary()
owner.splitViewController.show(.secondary)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment