Adding Behavior to Transition Buttons in UISplitViewController for Different Display Modes

37 Views Asked by At

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.

0

There are 0 best solutions below