Last active
July 22, 2023 08:34
-
-
Save yosshi4486/20f48789fb117a2e907658ed384a35a8 to your computer and use it in GitHub Desktop.
An UIViewControllerRepresentable wrapper of UISplitViewController
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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