Adaptive show detail segue transformed to modal instead of push on iPhone when master view controller is a UITabBarController

后端 未结 3 1041
既然无缘
既然无缘 2021-02-07 09:41

In XCode 6, if you create a new project based on the Master-Detail Application template, you get a universal storyboard that is supposed to be good for all devices.

When

相关标签:
3条回答
  • 2021-02-07 10:10

    Re-watching videos from WWDC14 I think I've found a better answer.

    1. Use a custom UISplitViewController (subclass)
    2. Override the showDetailViewController operation
    3. Use the traitCollection to determine the class of the UISplitViewController
    4. If the horizontal class is Compact, get the navigationController to call showViewController

    Here is the the code of the custom UISplitViewController :

    import UIKit
    
    class CustomSplitViewController: UISplitViewController {
    
        override func showDetailViewController(vc: UIViewController!, sender: AnyObject!) {
    
            if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
                if let tabBarController = self.viewControllers[0] as? UITabBarController {
                    if let navigationController = tabBarController.selectedViewController as? UINavigationController {
                        navigationController.showViewController(vc, sender: sender)
                        return
                    }
                }
            }
    
            super.showDetailViewController(vc, sender: sender)
        }
    }
    

    Do not forget to the set the custom class in the storyboard.

    Tested in the simulator of iPhone 6, iPhone 6+ and iPad Air and worked as expected.

    0 讨论(0)
  • 2021-02-07 10:21

    The docs state when the split controller is collapsed, it handles showDetail by calling show on the master view controller, which in your case is a tab controller. You need to forward that on to the child nav controller as follows:

    1. Make a tab controller subclass.
    2. In the storyboard set the tab controller to use the new subclass.
    3. Add this method to the subclass:
    - (void)showViewController:(UIViewController *)vc sender:(id)sender{
        [self.viewControllers.firstObject showViewController:vc sender:sender];
    }
    

    This forwards it on to the nav controller in the first tab.

    0 讨论(0)
  • 2021-02-07 10:27

    Unfortunately, the selected answer didn't work for me. However, I did eventually manage to solve the problem:

    1. Subclass UISplitViewController and set the new class in Interface Builder.
    2. Make the new class conform to UISplitViewControllerDelegate:

      required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
          self.delegate = self
      }
      
    3. Implement these two methods:

      func splitViewController(_ splitViewController: UISplitViewController,
                               collapseSecondary secondaryViewController:UIViewController,
                               onto primaryViewController:UIViewController) -> Bool {
          return true
      }
      
      func splitViewController(_ splitViewController: UISplitViewController,
                               showDetail vc: UIViewController,
                               sender: Any?) -> Bool {
      
          if splitViewController.isCollapsed {
              guard let tabBarController = splitViewController.viewControllers.first as? UITabBarController else { return false }
              guard let selectedNavigationViewController = tabBarController.selectedViewController as? UINavigationController else { return false }
      
              // Push view controller
              var detailViewController = vc
              if let navController = vc as? UINavigationController, let topViewController = navController.topViewController {
                  detailViewController = topViewController
              }
              selectedNavigationViewController.pushViewController(detailViewController, animated: true)
              return true
          }
          return false
      }
      
    0 讨论(0)
提交回复
热议问题