Skip to content

Instantly share code, notes, and snippets.

@jamesrochabrun
Created May 1, 2020 01:19
Show Gist options
  • Save jamesrochabrun/0efa6091b0002e70efb195cab1daf431 to your computer and use it in GitHub Desktop.
Save jamesrochabrun/0efa6091b0002e70efb195cab1daf431 to your computer and use it in GitHub Desktop.
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
/// 1 - Set view Controllers using `TabBarViewModel`
/// 2 - This iteration will create a master veiw controller embedded in a navigation controller for each tab.
/// 3 - `inSplitViewControllerIfSupported` is a `UINavigationController` extension method that will embed it in a `UISplitViewController` if supported.
/// we will see the implementation later.
viewControllers = TabBarViewModel.allCases.map { NavigationController(rootViewController: $0.masterViewController).inSplitViewControllerIfSupported(for: $0) }
}
}
/// The view model.
enum TabBarViewModel: String, CaseIterable {
case home
case search
case camera
case notifications
case profile
/// the tab bar icon
var icon: UIImage? {
switch self {
case .home: return UIImage(systemName: "house.fill")
case .search: return UIImage(systemName: "magnifyingglass")
case .camera: return UIImage(systemName: "plus.app")
case .notifications: return UIImage(systemName: "suit.heart")
case .profile: return UIImage(systemName: "person")
}
}
/// the tab bar title
var title: String {
rawValue
}
/// the master `topViewController` it instantiates a view controller using a convenient method for `UIStoryboards`.
var masterViewController: UIViewController {
switch self {
case .home: return HomeViewController.instantiate(from: "Main")
case .search: return SearchViewController.instantiate(from: "Main")
case .camera: return HomeViewController.instantiate(from: "Main")
case .notifications: return NotificationsViewController.instantiate(from: "Main")
case .profile: return UserProfileViewController.instantiate(from: "Main")
}
}
/// 4 - It defines if a tab should use a `UISplitViewController` as root or not.
var inSplitViewController: Bool {
switch self {
case .profile:
return true
default:
return false
}
}
}
extension UINavigationController {
/// 5 - This extension returns a `SplitViewController` instance with the master and an `EmptyDetailViewcontroller` instance
/// as a detail, if supported else will return self.
func inSplitViewControllerIfSupported(for viewModel: TabBarViewModel) -> UIViewController {
guard viewModel.inSplitViewController else {
self.tabBarItem.image = viewModel.icon
return self }
let splitViewController = SplitViewController(viewControllers: [self, EmptyDetailViewcontroller()])
splitViewController.tabBarItem.image = viewModel.icon
return splitViewController
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment