ContainerView with multiple embed segues

前端 未结 7 2083
走了就别回头了
走了就别回头了 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.

提交回复
热议问题