ContainerView with multiple embed segues

前端 未结 7 1993
走了就别回头了
走了就别回头了 2021-01-30 10:38

Is there a way to have a single ContainerView with multiple embed segues? The aim is for a ContainerView to hold a few different ViewControllers depending on what buttons have b

相关标签:
7条回答
  • 2021-01-30 10:56

    I struggled with this for a long time, too. I had the case where I had different, but similar embedded table view controllers that I wanted to show depending on a parameter that was set in the segue to the view controller. What worked was to put in the embedded container with an IBOutlet in the view controller. The container can have size constraints set in IB. However, don't make any embed segues in IB. Then in viewDidLoad, I programmatically add the correct view controller and pin its edges to the embed container.

    The heart of this approach is seen in the following code (Swift 4):

    extension UIView {
        func pinToParent() {
            self.translatesAutoresizingMaskIntoConstraints = false
            let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]
            NSLayoutConstraint.activate(attributes.map {
                NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: self.superview, attribute: $0, multiplier: 1, constant: 0)
            })
        }
    }
    
    class ColorVC: UIViewController {
    
        @IBOutlet weak var tableContainer: UIView!
        var color : rgb = .red
    
        fileprivate var colorTableVC : ColorTableVC?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            switch color {
            case .red:
                colorTableVC = RedTableVC.init(style: .plain)
            case .green:
                colorTableVC = GreenTableVC.init(style: .plain)
            case .blue:
                colorTableVC = BlueTableVC.init(style: .plain)
            }
            if let vc = colorTableVC {
                if (vc.view) != nil {
                    self.addChildViewController(vc)
                    tableContainer.addSubview(vc.view)
                    vc.view.pinToParent()
                    vc.didMove(toParentViewController: self)
                }
            }
        }
    }
    

    In the ColorVC, one sees the container IBOutlet and the "color" parameter set by the main table view controller. The RedTableVC, GreenTableVC, and BlueTableVC are all subclassed from ColorTableVC which is sub-classed from UITableViewController. The common heritage lets me use one "colorTableVC" variable to point to any of the instantiated controllers. (Not entirely necessary). But this does avoid duplicating code below to add the view in the heirarchy and pin the new controller to the container view. At the top, I made an extension on UIView to pin a view to its parents edges.

    The following image shows how the project and particularly the view controller on the right was set up in IB. For this example, I made the height of the "embedded" controller half the height of the main view controller - so when you rotate the device, one can see that the constraints set in IB are indeed applied.

    0 讨论(0)
  • 2021-01-30 10:57

    No, there is no way to have multiple embed segues to one container view. One way to do all the setup in IB, would be to make the embedded controller a UITabBarController (with the tab bar hidden). You can then have as many controllers in the tabs as you want, and switch to them in code using the selectedIndex property of UITabBarController.

    0 讨论(0)
  • 2021-01-30 11:04

    I recognize this question is a bit old, but I wanted to answer in case you're still looking or other people find this. I had a similar issue and I worked around it.

    In short, you'll have three layers:
    - an external view controller ("ExternalViewController")
    - a view controller manager ("ViewControllerManager")
    - the child view controllers you actually want to be switching between ("ChildViewController")

    Use a container view in ExternalViewController with an embed segue to the ViewControllerManager. ViewControllerManager itself would then hold other ChildViewControllers programmatically as described in this Apple documentation, specifically the section on adding and removing a child.

    When you add a child view controller, set its frame to be the same as the ViewControllerManager's frame (since you're doing this inside the ViewControllerManager, set the child's frame equal to self.view.frame). You will also need some logic and an external control to do the switching inside of ExternalViewController, of course.

    Hope this helps!

    0 讨论(0)
  • 2021-01-30 11:05

    Yes, I was able to achieve what you're looking for inspired by @rdelmar post. What you need to do is to embed a UITabBarViewController into your container view. Then you programmatically choose which controller you like to present. You might also like to hide the tab bar.

    If you want you can also hide the tab bars seen in the storyboard file

    You can choose the view controller you want to present by subclassing the UITabBarController:

    override func viewDidLoad() {
        super.viewDidLoad()
        self.selectedIndex = 1
    }
    

    You can hide the tab bar in your view controller by calling self.tabBarController?.tabBar.hidden = truein viewDidLoad().

    0 讨论(0)
  • 2021-01-30 11:09

    I've achieved that by making use of -shouldPerformSegueWithIdentifier:sender:. I have a container that is passed an object and depending on the type of this object decides which child view controller to show.

    The structure seems a little over complicated but allows the base view controller to ignore the different types of tasks I have, leaving that to the container view controller. The container view controller has then multiple container views which segues are only performed depending on the type of task.

    I don't know if you can actually perform the embed segues manually by calling -performSegueWithIdentifier:sender: but that could also be a possibility.

    0 讨论(0)
  • 2021-01-30 11:10

    I found this wonderful article that explained exactly how to do it: http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers

    you get your container and can call any view controller behind, there is a bit of set up to have everything linked but once done, you get a still useable storyboard.

    0 讨论(0)
提交回复
热议问题