I want to use a UITabBarViewController when on iPhone in portrait and a UISplitViewController when on iPhone 6/6+ in landscape or iPad in either orientation. When on iPad or iPhone 6/6+ landscape, the tab bar items present themselves as UITableViewCells in the topmost view controller.
I would really like for the calling object to not have to worry about device or orientation, but instead pass as input the view controllers that are in the tab bar on iPhone in portrait and in the root view controller on iPad and iPhone 6/6+ in landscape.
Here's a visual representation of what I mean:
I think it's likely possible to use the tab bar images property to place an image in the table view cells, as well. I'm doing this in Swift, and I think a strategy for this might be something like this:
class ResponsiveRootViewController: UIViewController {
var viewControllers: NSArray?
var responsiveTabBarController: UITabBarController?
var responsiveSplitViewController: UISplitViewController?
var responsiveRootViewController: UITableViewController?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
}
}
Is this possible? Has this already been done? Should I instead implement a tab bar view controller that hides its tab bar in landscape (this seems super hacky to me)? How do I add my generated root table view controller (the one which I'd like the tab bar items to exist in) into the view hierarchy when the orientation changes?
I've worked out how to do this, and while it doesn't contain solution anyone needs, I have included the code below which you can customise to your specific needs:
SplitTabBarViewController.swift
var rootViewControllers: [UIViewController]
var detailViewController: UIViewController
var aTabBarController: UITabBarController
var aSplitViewController: UISplitViewController
var primaryTabBarTableViewController: SplitTabBarPrimaryTableViewController
init(rootViewControllers: [UIViewController], detailViewController: UIViewController) {
self.rootViewControllers = rootViewControllers
self.detailViewController = detailViewController
self.aTabBarController = UITabBarController()
self.aTabBarController.viewControllers = self.rootViewControllers
self.aSplitViewController = UISplitViewController()
self.primaryTabBarTableViewController = SplitTabBarPrimaryTableViewController(rootViewControllers: self.rootViewControllers)
self.aSplitViewController.viewControllers = [self.primaryTabBarTableViewController, self.detailViewController]
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
if (UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation)) {
self.addSplitViewController()
} else {
self.addTabBarController()
}
}
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
self.removeTabBarController()
self.addSplitViewController()
} else {
self.removeSplitViewController()
self.addTabBarController()
}
}
func addTabBarController() {
self.view.addSubview(self.aTabBarController.view)
self.addChildViewController(self.aTabBarController)
self.aTabBarController.view.frame = self.view.frame
}
func removeTabBarController() {
self.aTabBarController.removeFromParentViewController()
self.aTabBarController.view.removeFromSuperview()
}
func addSplitViewController() {
self.view.addSubview(self.aSplitViewController.view)
self.addChildViewController(self.aSplitViewController)
self.aSplitViewController.view.frame = self.view.frame
}
func removeSplitViewController() {
self.aSplitViewController.removeFromParentViewController()
self.aSplitViewController.view.removeFromSuperview()
}
SplitTabBarPrimaryTableViewController.swift
var rootViewControllers: [UIViewController]
init(rootViewControllers: [UIViewController]) {
self.rootViewControllers = rootViewControllers;
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "reuseIdentifier")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.rootViewControllers.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = self.rootViewControllers[indexPath.row].title
return cell
}