I'm planning to use UISplitViewController to implement a side menu. The initial display format of the UISplitViewController varies depending on the screen size:
(a) Side menu and main view displayed side by side (iPad landscape mode). (b) Only the main view is shown, and the side menu overlaps the main view when shown (iPad portrait mode). (c) Only the side menu is displayed, and showing the main view triggers a push transition (iPad multitasking/iPhone).
For each of these cases, I want to add specific behaviors to the transition buttons displayed in the side menu:
(a) Do nothing. (b) Close the side menu. (c) Transition to the main view.
I have been able to achieve (a) and (b) using the following code:
import UIKit
class ViewController: UIViewController {
let splitVC = UISplitViewController(style: .doubleColumn)
var hideBarButton: UIBarButtonItem!
var showBarButton: UIBarButtonItem!
var isExplorerHidden = false
override func viewDidLoad() {
super.viewDidLoad()
let menuVC = MenuViewController()
let mainVC = UIViewController()
menuVC.view.backgroundColor = .systemBrown
mainVC.view.backgroundColor = .systemMint
splitVC.viewControllers = [
UINavigationController(rootViewController: menuVC),
UINavigationController(rootViewController: mainVC)
]
splitVC.modalPresentationStyle = .fullScreen
present(splitVC, animated: false)
splitVC.show(.primary)
splitVC.presentsWithGesture = false
hideBarButton = UIBarButtonItem(
image: UIImage(systemName: "arrow.up.left.and.arrow.down.right"),
style: .plain,
target: self,
action: #selector(didTapHideBarButton))
showBarButton = UIBarButtonItem(
image: UIImage(systemName: "sidebar.left"),
style: .plain,
target: self,
action: #selector(didTapShowBarButton))
mainVC.navigationItem.leftBarButtonItems = [hideBarButton, showBarButton]
for barButtonItem in mainVC.navigationItem.leftBarButtonItems! {
barButtonItem.tintColor = .black
}
showBarButton.isHidden = true
menuVC.delegate = self
splitVC.delegate = self
}
@objc func didTapHideBarButton() {
hideBarButton.isHidden = true
showBarButton.isHidden = false
splitVC.show(.secondary)
splitVC.hide(.primary)
}
@objc func didTapShowBarButton() {
hideBarButton.isHidden = false
showBarButton.isHidden = true
splitVC.show(.primary)
splitVC.hide(.secondary)
}
private func updateHideAndShowButtonState() {
hideBarButton.isHidden = isExplorerHidden
showBarButton.isHidden = !isExplorerHidden
}
}
extension ViewController: UISplitViewControllerDelegate {
func splitViewController(_ svc: UISplitViewController, willShow column: UISplitViewController.Column) {
guard column.rawValue == 0 else { return }
isExplorerHidden = false
updateHideAndShowButtonState()
}
func splitViewController(_ svc: UISplitViewController, willHide column: UISplitViewController.Column) {
guard column.rawValue == 0 else { return }
isExplorerHidden = true
updateHideAndShowButtonState()
}
}
extension ViewController: MenuViewControllerDelegate {
func hideMenu() {
// Called when the transition button is pressed.
if splitVC.displayMode != .oneBesideSecondary {
didTapHideBarButton()
}
}
}
https://github.com/Se1getsu/splitvc-test/blob/main/splitvc-test/ViewController.swift
However, I'm struggling to figure out how to implement the conditional branching for (c). If anyone has any ideas or suggestions, please let me know.