Use UITabBarViewController in portrait but UISplitViewController in landscape in a Universal app

你说的曾经没有我的故事 提交于 2019-12-09 12:56:11

问题


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?


回答1:


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
}


来源:https://stackoverflow.com/questions/29723231/use-uitabbarviewcontroller-in-portrait-but-uisplitviewcontroller-in-landscape-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!